cpufunc.h revision 206713
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: head/sys/mips/include/cpufunc.h 206713 2010-04-16 23:46:30Z jmallett $ 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{ 72178172Simp __asm __volatile (".set noreorder\n\t" 73178172Simp "nop\n\t" 74178172Simp "nop\n\t" 75178172Simp "nop\n\t" 76178172Simp "nop\n\t" 77178172Simp "nop\n\t" 78178172Simp "nop\n\t" 79178172Simp "nop\n\t" 80178172Simp "nop\n\t" 81178172Simp ".set reorder\n\t" 82178172Simp : : : "memory"); 83178172Simp} 84178172Simp 85178172Simpstatic __inline void 86206713Sjmallettmips_cp0_sync(void) 87206713Sjmallett{ 88206713Sjmallett __asm __volatile (__XSTRING(COP0_SYNC)); 89206713Sjmallett} 90206713Sjmallett 91206713Sjmallettstatic __inline void 92178172Simpmips_wbflush(void) 93178172Simp{ 94178172Simp __asm __volatile ("sync" : : : "memory"); 95178172Simp mips_barrier(); 96178172Simp} 97178172Simp 98178172Simpstatic __inline void 99178172Simpmips_read_membar(void) 100178172Simp{ 101178172Simp /* Nil */ 102178172Simp} 103178172Simp 104178172Simpstatic __inline void 105178172Simpmips_write_membar(void) 106178172Simp{ 107178172Simp mips_wbflush(); 108178172Simp} 109178172Simp 110178172Simp#ifdef _KERNEL 111206713Sjmallett#if defined(__mips_n32) || defined(__mips_n64) 112178172Simp#define MIPS_RDRW64_COP0(n,r) \ 113178172Simpstatic __inline uint64_t \ 114178172Simpmips_rd_ ## n (void) \ 115178172Simp{ \ 116178172Simp int v0; \ 117178172Simp __asm __volatile ("dmfc0 %[v0], $"__XSTRING(r)";" \ 118178172Simp : [v0] "=&r"(v0)); \ 119178172Simp mips_barrier(); \ 120178172Simp return (v0); \ 121178172Simp} \ 122178172Simpstatic __inline void \ 123178172Simpmips_wr_ ## n (uint64_t a0) \ 124178172Simp{ \ 125178172Simp __asm __volatile ("dmtc0 %[a0], $"__XSTRING(r)";" \ 126178172Simp __XSTRING(COP0_SYNC)";" \ 127178172Simp "nop;" \ 128178172Simp "nop;" \ 129178172Simp : \ 130178172Simp : [a0] "r"(a0)); \ 131178172Simp mips_barrier(); \ 132178172Simp} struct __hack 133178172Simp 134206713Sjmallett#if defined(__mips_n64) 135178172SimpMIPS_RDRW64_COP0(entrylo0, MIPS_COP_0_TLB_LO0); 136178172SimpMIPS_RDRW64_COP0(entrylo1, MIPS_COP_0_TLB_LO1); 137178172SimpMIPS_RDRW64_COP0(entryhi, MIPS_COP_0_TLB_HI); 138178172SimpMIPS_RDRW64_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK); 139206713Sjmallett#endif 140178172SimpMIPS_RDRW64_COP0(xcontext, MIPS_COP_0_TLB_XCONTEXT); 141178172Simp 142178172Simp#undef MIPS_RDRW64_COP0 143178172Simp#endif 144178172Simp 145178172Simp#define MIPS_RDRW32_COP0(n,r) \ 146178172Simpstatic __inline uint32_t \ 147178172Simpmips_rd_ ## n (void) \ 148178172Simp{ \ 149178172Simp int v0; \ 150178172Simp __asm __volatile ("mfc0 %[v0], $"__XSTRING(r)";" \ 151178172Simp : [v0] "=&r"(v0)); \ 152178172Simp mips_barrier(); \ 153178172Simp return (v0); \ 154178172Simp} \ 155178172Simpstatic __inline void \ 156178172Simpmips_wr_ ## n (uint32_t a0) \ 157178172Simp{ \ 158178172Simp __asm __volatile ("mtc0 %[a0], $"__XSTRING(r)";" \ 159178172Simp __XSTRING(COP0_SYNC)";" \ 160178172Simp "nop;" \ 161178172Simp "nop;" \ 162178172Simp : \ 163178172Simp : [a0] "r"(a0)); \ 164178172Simp mips_barrier(); \ 165178172Simp} struct __hack 166178172Simp 167202031Simp#define MIPS_RDRW32_COP0_SEL(n,r,s) \ 168202031Simpstatic __inline uint32_t \ 169202031Simpmips_rd_ ## n ## s(void) \ 170202031Simp{ \ 171202031Simp int v0; \ 172202031Simp __asm __volatile ("mfc0 %[v0], $"__XSTRING(r)", "__XSTRING(s)";" \ 173202031Simp : [v0] "=&r"(v0)); \ 174202031Simp mips_barrier(); \ 175202031Simp return (v0); \ 176202031Simp} \ 177202031Simpstatic __inline void \ 178202031Simpmips_wr_ ## n ## s(uint32_t a0) \ 179202031Simp{ \ 180202031Simp __asm __volatile ("mtc0 %[a0], $"__XSTRING(r)", "__XSTRING(s)";" \ 181202031Simp __XSTRING(COP0_SYNC)";" \ 182202031Simp "nop;" \ 183202031Simp "nop;" \ 184202031Simp : \ 185202031Simp : [a0] "r"(a0)); \ 186202031Simp mips_barrier(); \ 187202031Simp} struct __hack 188202031Simp 189178172Simp#ifdef TARGET_OCTEON 190178172Simpstatic __inline void mips_sync_icache (void) 191178172Simp{ 192202031Simp __asm __volatile ( 193202031Simp ".set push\n" 194202031Simp ".set mips64\n" 195202031Simp ".word 0x041f0000\n" /* xxx ICACHE */ 196202031Simp "nop\n" 197202031Simp ".set pop\n" 198202031Simp : : ); 199178172Simp} 200178172Simp#endif 201178172Simp 202178172SimpMIPS_RDRW32_COP0(compare, MIPS_COP_0_COMPARE); 203178172SimpMIPS_RDRW32_COP0(config, MIPS_COP_0_CONFIG); 204202031SimpMIPS_RDRW32_COP0_SEL(config, MIPS_COP_0_CONFIG, 1); 205202031SimpMIPS_RDRW32_COP0_SEL(config, MIPS_COP_0_CONFIG, 2); 206202031SimpMIPS_RDRW32_COP0_SEL(config, MIPS_COP_0_CONFIG, 3); 207178172SimpMIPS_RDRW32_COP0(count, MIPS_COP_0_COUNT); 208178172SimpMIPS_RDRW32_COP0(index, MIPS_COP_0_TLB_INDEX); 209178172SimpMIPS_RDRW32_COP0(wired, MIPS_COP_0_TLB_WIRED); 210178172SimpMIPS_RDRW32_COP0(cause, MIPS_COP_0_CAUSE); 211178172SimpMIPS_RDRW32_COP0(status, MIPS_COP_0_STATUS); 212178172Simp 213178172Simp/* XXX: Some of these registers are specific to MIPS32. */ 214206713Sjmallett#if !defined(__mips_n64) 215178172SimpMIPS_RDRW32_COP0(entrylo0, MIPS_COP_0_TLB_LO0); 216178172SimpMIPS_RDRW32_COP0(entrylo1, MIPS_COP_0_TLB_LO1); 217178172SimpMIPS_RDRW32_COP0(entryhi, MIPS_COP_0_TLB_HI); 218178172SimpMIPS_RDRW32_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK); 219206713Sjmallett#endif 220178172SimpMIPS_RDRW32_COP0(prid, MIPS_COP_0_PRID); 221206713Sjmallett/* XXX 64-bit? */ 222206713SjmallettMIPS_RDRW32_COP0_SEL(prid, MIPS_COP_0_PRID, 1); 223178172SimpMIPS_RDRW32_COP0(watchlo, MIPS_COP_0_WATCH_LO); 224202031SimpMIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 1); 225202031SimpMIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 2); 226202031SimpMIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 3); 227178172SimpMIPS_RDRW32_COP0(watchhi, MIPS_COP_0_WATCH_HI); 228202031SimpMIPS_RDRW32_COP0_SEL(watchhi, MIPS_COP_0_WATCH_HI, 1); 229202031SimpMIPS_RDRW32_COP0_SEL(watchhi, MIPS_COP_0_WATCH_HI, 2); 230202031SimpMIPS_RDRW32_COP0_SEL(watchhi, MIPS_COP_0_WATCH_HI, 3); 231204635Sgnn 232204635SgnnMIPS_RDRW32_COP0_SEL(perfcnt, MIPS_COP_0_PERFCNT, 0); 233204635SgnnMIPS_RDRW32_COP0_SEL(perfcnt, MIPS_COP_0_PERFCNT, 1); 234204635SgnnMIPS_RDRW32_COP0_SEL(perfcnt, MIPS_COP_0_PERFCNT, 2); 235204635SgnnMIPS_RDRW32_COP0_SEL(perfcnt, MIPS_COP_0_PERFCNT, 3); 236204635Sgnn 237178172Simp#undef MIPS_RDRW32_COP0 238178172Simp 239178172Simpstatic __inline register_t 240178172Simpintr_disable(void) 241178172Simp{ 242178172Simp register_t s; 243178172Simp 244178172Simp s = mips_rd_status(); 245178172Simp mips_wr_status(s & ~MIPS_SR_INT_IE); 246178172Simp 247206713Sjmallett return (s & MIPS_SR_INT_IE); 248178172Simp} 249178172Simp 250178172Simpstatic __inline register_t 251178172Simpintr_enable(void) 252178172Simp{ 253178172Simp register_t s; 254178172Simp 255178172Simp s = mips_rd_status(); 256178172Simp mips_wr_status(s | MIPS_SR_INT_IE); 257178172Simp 258178172Simp return (s); 259178172Simp} 260178172Simp 261206713Sjmallettstatic __inline void 262206713Sjmallettintr_restore(register_t ie) 263206713Sjmallett{ 264206713Sjmallett if (ie == MIPS_SR_INT_IE) { 265206713Sjmallett intr_enable(); 266206713Sjmallett } 267206713Sjmallett} 268178172Simp 269178172Simpstatic __inline void 270178172Simpbreakpoint(void) 271178172Simp{ 272178172Simp __asm __volatile ("break"); 273178172Simp} 274178172Simp 275205675Sneel#if defined(__GNUC__) && !defined(__mips_o32) 276205675Sneelstatic inline uint64_t 277205675Sneelmips3_ld(const volatile uint64_t *va) 278205675Sneel{ 279205675Sneel uint64_t rv; 280205675Sneel 281205675Sneel#if defined(_LP64) 282205675Sneel rv = *va; 283205675Sneel#else 284205675Sneel __asm volatile("ld %0,0(%1)" : "=d"(rv) : "r"(va)); 285205675Sneel#endif 286205675Sneel 287205675Sneel return (rv); 288205675Sneel} 289205675Sneel 290205675Sneelstatic inline void 291205675Sneelmips3_sd(volatile uint64_t *va, uint64_t v) 292205675Sneel{ 293205675Sneel#if defined(_LP64) 294205675Sneel *va = v; 295205675Sneel#else 296205675Sneel __asm volatile("sd %0,0(%1)" :: "r"(v), "r"(va)); 297205675Sneel#endif 298205675Sneel} 299205675Sneel#else 300205675Sneeluint64_t mips3_ld(volatile uint64_t *va); 301205675Sneelvoid mips3_sd(volatile uint64_t *, uint64_t); 302205675Sneel#endif /* __GNUC__ */ 303205675Sneel 304178172Simp#endif /* _KERNEL */ 305178172Simp 306178172Simp#define readb(va) (*(volatile uint8_t *) (va)) 307178172Simp#define readw(va) (*(volatile uint16_t *) (va)) 308178172Simp#define readl(va) (*(volatile uint32_t *) (va)) 309178172Simp 310178172Simp#define writeb(va, d) (*(volatile uint8_t *) (va) = (d)) 311178172Simp#define writew(va, d) (*(volatile uint16_t *) (va) = (d)) 312178172Simp#define writel(va, d) (*(volatile uint32_t *) (va) = (d)) 313178172Simp 314178172Simp/* 315178172Simp * I/O macros. 316178172Simp */ 317178172Simp 318178172Simp#define outb(a,v) (*(volatile unsigned char*)(a) = (v)) 319178172Simp#define out8(a,v) (*(volatile unsigned char*)(a) = (v)) 320178172Simp#define outw(a,v) (*(volatile unsigned short*)(a) = (v)) 321178172Simp#define out16(a,v) outw(a,v) 322178172Simp#define outl(a,v) (*(volatile unsigned int*)(a) = (v)) 323178172Simp#define out32(a,v) outl(a,v) 324178172Simp#define inb(a) (*(volatile unsigned char*)(a)) 325178172Simp#define in8(a) (*(volatile unsigned char*)(a)) 326178172Simp#define inw(a) (*(volatile unsigned short*)(a)) 327178172Simp#define in16(a) inw(a) 328178172Simp#define inl(a) (*(volatile unsigned int*)(a)) 329178172Simp#define in32(a) inl(a) 330178172Simp 331178172Simp#define out8rb(a,v) (*(volatile unsigned char*)(a) = (v)) 332178172Simp#define out16rb(a,v) (__out16rb((volatile uint16_t *)(a), v)) 333178172Simp#define out32rb(a,v) (__out32rb((volatile uint32_t *)(a), v)) 334178172Simp#define in8rb(a) (*(volatile unsigned char*)(a)) 335178172Simp#define in16rb(a) (__in16rb((volatile uint16_t *)(a))) 336178172Simp#define in32rb(a) (__in32rb((volatile uint32_t *)(a))) 337178172Simp 338178172Simp#define _swap_(x) (((x) >> 24) | ((x) << 24) | \ 339178172Simp (((x) >> 8) & 0xff00) | (((x) & 0xff00) << 8)) 340178172Simp 341178172Simpstatic __inline void __out32rb(volatile uint32_t *, uint32_t); 342178172Simpstatic __inline void __out16rb(volatile uint16_t *, uint16_t); 343178172Simpstatic __inline uint32_t __in32rb(volatile uint32_t *); 344178172Simpstatic __inline uint16_t __in16rb(volatile uint16_t *); 345178172Simp 346178172Simpstatic __inline void 347178172Simp__out32rb(volatile uint32_t *a, uint32_t v) 348178172Simp{ 349178172Simp uint32_t _v_ = v; 350178172Simp 351178172Simp _v_ = _swap_(_v_); 352178172Simp out32(a, _v_); 353178172Simp} 354178172Simp 355178172Simpstatic __inline void 356178172Simp__out16rb(volatile uint16_t *a, uint16_t v) 357178172Simp{ 358178172Simp uint16_t _v_; 359178172Simp 360178172Simp _v_ = ((v >> 8) & 0xff) | (v << 8); 361178172Simp out16(a, _v_); 362178172Simp} 363178172Simp 364178172Simpstatic __inline uint32_t 365178172Simp__in32rb(volatile uint32_t *a) 366178172Simp{ 367178172Simp uint32_t _v_; 368178172Simp 369178172Simp _v_ = in32(a); 370178172Simp _v_ = _swap_(_v_); 371178172Simp return _v_; 372178172Simp} 373178172Simp 374178172Simpstatic __inline uint16_t 375178172Simp__in16rb(volatile uint16_t *a) 376178172Simp{ 377178172Simp uint16_t _v_; 378178172Simp 379178172Simp _v_ = in16(a); 380178172Simp _v_ = ((_v_ >> 8) & 0xff) | (_v_ << 8); 381178172Simp return _v_; 382178172Simp} 383178172Simp 384178172Simpvoid insb(uint8_t *, uint8_t *,int); 385178172Simpvoid insw(uint16_t *, uint16_t *,int); 386178172Simpvoid insl(uint32_t *, uint32_t *,int); 387178172Simpvoid outsb(uint8_t *, const uint8_t *,int); 388178172Simpvoid outsw(uint16_t *, const uint16_t *,int); 389178172Simpvoid outsl(uint32_t *, const uint32_t *,int); 390178172Simpu_int loadandclear(volatile u_int *addr); 391178172Simp 392178172Simp#endif /* !_MACHINE_CPUFUNC_H_ */ 393