cpufunc.h revision 204635
1178172Simp/* $OpenBSD: pio.h,v 1.2 1998/09/15 10:50:12 pefo Exp $ */ 2178172Simp 3178172Simp/* 4178172Simp * Copyright (c) 1995-1999 Per Fogelstrom. All rights reserved. 5178172Simp * 6178172Simp * Redistribution and use in source and binary forms, with or without 7178172Simp * modification, are permitted provided that the following conditions 8178172Simp * are met: 9178172Simp * 1. Redistributions of source code must retain the above copyright 10178172Simp * notice, this list of conditions and the following disclaimer. 11178172Simp * 2. Redistributions in binary form must reproduce the above copyright 12178172Simp * notice, this list of conditions and the following disclaimer in the 13178172Simp * documentation and/or other materials provided with the distribution. 14178172Simp * 3. All advertising materials mentioning features or use of this software 15178172Simp * must display the following acknowledgement: 16178172Simp * This product includes software developed by Per Fogelstrom. 17178172Simp * 4. The name of the author may not be used to endorse or promote products 18178172Simp * derived from this software without specific prior written permission 19178172Simp * 20178172Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 21178172Simp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22178172Simp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23178172Simp * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 24178172Simp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 25178172Simp * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26178172Simp * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27178172Simp * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28178172Simp * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29178172Simp * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30178172Simp * 31178172Simp * JNPR: cpufunc.h,v 1.5 2007/08/09 11:23:32 katta 32178172Simp * $FreeBSD: head/sys/mips/include/cpufunc.h 204635 2010-03-03 15:05:58Z gnn $ 33178172Simp */ 34178172Simp 35178172Simp#ifndef _MACHINE_CPUFUNC_H_ 36178172Simp#define _MACHINE_CPUFUNC_H_ 37178172Simp 38178172Simp#include <sys/types.h> 39178172Simp#include <machine/cpuregs.h> 40178172Simp 41178172Simp/* 42178172Simp * These functions are required by user-land atomi ops 43178172Simp */ 44178172Simp 45178172Simpstatic __inline void 46178172Simpmips_barrier(void) 47178172Simp{ 48178172Simp __asm __volatile (".set noreorder\n\t" 49178172Simp "nop\n\t" 50178172Simp "nop\n\t" 51178172Simp "nop\n\t" 52178172Simp "nop\n\t" 53178172Simp "nop\n\t" 54178172Simp "nop\n\t" 55178172Simp "nop\n\t" 56178172Simp "nop\n\t" 57178172Simp ".set reorder\n\t" 58178172Simp : : : "memory"); 59178172Simp} 60178172Simp 61178172Simpstatic __inline void 62178172Simpmips_wbflush(void) 63178172Simp{ 64178172Simp __asm __volatile ("sync" : : : "memory"); 65178172Simp mips_barrier(); 66178172Simp#if 0 67178172Simp __asm __volatile("mtc0 %0, $12\n" /* MIPS_COP_0_STATUS */ 68178172Simp : : "r" (flag)); 69178172Simp#endif 70178172Simp} 71178172Simp 72178172Simpstatic __inline void 73178172Simpmips_read_membar(void) 74178172Simp{ 75178172Simp /* Nil */ 76178172Simp} 77178172Simp 78178172Simpstatic __inline void 79178172Simpmips_write_membar(void) 80178172Simp{ 81178172Simp mips_wbflush(); 82178172Simp} 83178172Simp 84178172Simp#ifdef _KERNEL 85178172Simp 86178172Simpstatic __inline void 87178172Simpmips_tlbp(void) 88178172Simp{ 89178172Simp __asm __volatile ("tlbp"); 90178172Simp mips_barrier(); 91178172Simp#if 0 92178172Simp register_t ret; 93178172Simp register_t tmp; 94178172Simp 95178172Simp __asm __volatile("mfc0 %0, $12\n" /* MIPS_COP_0_STATUS */ 96178172Simp "and %1, %0, $~1\n" /* MIPS_SR_INT_IE */ 97178172Simp "mtc0 %1, $12\n" /* MIPS_COP_0_STATUS */ 98178172Simp : "=r" (ret), "=r" (tmp)); 99178172Simp return (ret); 100178172Simp#endif 101178172Simp} 102178172Simp 103178172Simpstatic __inline void 104178172Simpmips_tlbr(void) 105178172Simp{ 106178172Simp __asm __volatile ("tlbr"); 107178172Simp mips_barrier(); 108178172Simp} 109178172Simp 110178172Simpstatic __inline void 111178172Simpmips_tlbwi(void) 112178172Simp{ 113178172Simp __asm __volatile ("tlbwi"); 114178172Simp mips_barrier(); 115178172Simp#if 0 116178172Simp __asm __volatile("mfc %0, $12\n" /* MIPS_COP_0_STATUS */ 117178172Simp "or %0, %0, $1\n" /* MIPS_SR_INT_IE */ 118178172Simp "mtc0 %0, $12\n" /* MIPS_COP_0_STATUS */ 119178172Simp : "=r" (tmp)); 120178172Simp#endif 121178172Simp} 122178172Simp 123178172Simpstatic __inline void 124178172Simpmips_tlbwr(void) 125178172Simp{ 126178172Simp __asm __volatile ("tlbwr"); 127178172Simp mips_barrier(); 128178172Simp} 129178172Simp 130178172Simp 131178172Simp#if 0 /* XXX mips64 */ 132178172Simp 133178172Simp#define MIPS_RDRW64_COP0(n,r) \ 134178172Simpstatic __inline uint64_t \ 135178172Simpmips_rd_ ## n (void) \ 136178172Simp{ \ 137178172Simp int v0; \ 138178172Simp __asm __volatile ("dmfc0 %[v0], $"__XSTRING(r)";" \ 139178172Simp : [v0] "=&r"(v0)); \ 140178172Simp mips_barrier(); \ 141178172Simp return (v0); \ 142178172Simp} \ 143178172Simpstatic __inline void \ 144178172Simpmips_wr_ ## n (uint64_t a0) \ 145178172Simp{ \ 146178172Simp __asm __volatile ("dmtc0 %[a0], $"__XSTRING(r)";" \ 147178172Simp __XSTRING(COP0_SYNC)";" \ 148178172Simp "nop;" \ 149178172Simp "nop;" \ 150178172Simp : \ 151178172Simp : [a0] "r"(a0)); \ 152178172Simp mips_barrier(); \ 153178172Simp} struct __hack 154178172Simp 155178172SimpMIPS_RDRW64_COP0(entrylo0, MIPS_COP_0_TLB_LO0); 156178172SimpMIPS_RDRW64_COP0(entrylo1, MIPS_COP_0_TLB_LO1); 157178172SimpMIPS_RDRW64_COP0(entryhi, MIPS_COP_0_TLB_HI); 158178172SimpMIPS_RDRW64_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK); 159178172SimpMIPS_RDRW64_COP0(xcontext, MIPS_COP_0_TLB_XCONTEXT); 160178172Simp 161178172Simp#undef MIPS_RDRW64_COP0 162178172Simp#endif 163178172Simp 164178172Simp#define MIPS_RDRW32_COP0(n,r) \ 165178172Simpstatic __inline uint32_t \ 166178172Simpmips_rd_ ## n (void) \ 167178172Simp{ \ 168178172Simp int v0; \ 169178172Simp __asm __volatile ("mfc0 %[v0], $"__XSTRING(r)";" \ 170178172Simp : [v0] "=&r"(v0)); \ 171178172Simp mips_barrier(); \ 172178172Simp return (v0); \ 173178172Simp} \ 174178172Simpstatic __inline void \ 175178172Simpmips_wr_ ## n (uint32_t a0) \ 176178172Simp{ \ 177178172Simp __asm __volatile ("mtc0 %[a0], $"__XSTRING(r)";" \ 178178172Simp __XSTRING(COP0_SYNC)";" \ 179178172Simp "nop;" \ 180178172Simp "nop;" \ 181178172Simp : \ 182178172Simp : [a0] "r"(a0)); \ 183178172Simp mips_barrier(); \ 184178172Simp} struct __hack 185178172Simp 186202031Simp#define MIPS_RDRW32_COP0_SEL(n,r,s) \ 187202031Simpstatic __inline uint32_t \ 188202031Simpmips_rd_ ## n ## s(void) \ 189202031Simp{ \ 190202031Simp int v0; \ 191202031Simp __asm __volatile ("mfc0 %[v0], $"__XSTRING(r)", "__XSTRING(s)";" \ 192202031Simp : [v0] "=&r"(v0)); \ 193202031Simp mips_barrier(); \ 194202031Simp return (v0); \ 195202031Simp} \ 196202031Simpstatic __inline void \ 197202031Simpmips_wr_ ## n ## s(uint32_t a0) \ 198202031Simp{ \ 199202031Simp __asm __volatile ("mtc0 %[a0], $"__XSTRING(r)", "__XSTRING(s)";" \ 200202031Simp __XSTRING(COP0_SYNC)";" \ 201202031Simp "nop;" \ 202202031Simp "nop;" \ 203202031Simp : \ 204202031Simp : [a0] "r"(a0)); \ 205202031Simp mips_barrier(); \ 206202031Simp} struct __hack 207202031Simp 208178172Simp#ifdef TARGET_OCTEON 209178172Simpstatic __inline void mips_sync_icache (void) 210178172Simp{ 211202031Simp __asm __volatile ( 212202031Simp ".set push\n" 213202031Simp ".set mips64\n" 214202031Simp ".word 0x041f0000\n" /* xxx ICACHE */ 215202031Simp "nop\n" 216202031Simp ".set pop\n" 217202031Simp : : ); 218178172Simp} 219178172Simp#endif 220178172Simp 221178172SimpMIPS_RDRW32_COP0(compare, MIPS_COP_0_COMPARE); 222178172SimpMIPS_RDRW32_COP0(config, MIPS_COP_0_CONFIG); 223202031SimpMIPS_RDRW32_COP0_SEL(config, MIPS_COP_0_CONFIG, 1); 224202031SimpMIPS_RDRW32_COP0_SEL(config, MIPS_COP_0_CONFIG, 2); 225202031SimpMIPS_RDRW32_COP0_SEL(config, MIPS_COP_0_CONFIG, 3); 226178172SimpMIPS_RDRW32_COP0(count, MIPS_COP_0_COUNT); 227178172SimpMIPS_RDRW32_COP0(index, MIPS_COP_0_TLB_INDEX); 228178172SimpMIPS_RDRW32_COP0(wired, MIPS_COP_0_TLB_WIRED); 229178172SimpMIPS_RDRW32_COP0(cause, MIPS_COP_0_CAUSE); 230178172SimpMIPS_RDRW32_COP0(status, MIPS_COP_0_STATUS); 231178172Simp 232178172Simp/* XXX: Some of these registers are specific to MIPS32. */ 233178172SimpMIPS_RDRW32_COP0(entrylo0, MIPS_COP_0_TLB_LO0); 234178172SimpMIPS_RDRW32_COP0(entrylo1, MIPS_COP_0_TLB_LO1); 235178172SimpMIPS_RDRW32_COP0(entrylow, MIPS_COP_0_TLB_LOW); 236178172SimpMIPS_RDRW32_COP0(entryhi, MIPS_COP_0_TLB_HI); 237178172SimpMIPS_RDRW32_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK); 238178172SimpMIPS_RDRW32_COP0(prid, MIPS_COP_0_PRID); 239178172SimpMIPS_RDRW32_COP0(watchlo, MIPS_COP_0_WATCH_LO); 240202031SimpMIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 1); 241202031SimpMIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 2); 242202031SimpMIPS_RDRW32_COP0_SEL(watchlo, MIPS_COP_0_WATCH_LO, 3); 243178172SimpMIPS_RDRW32_COP0(watchhi, MIPS_COP_0_WATCH_HI); 244202031SimpMIPS_RDRW32_COP0_SEL(watchhi, MIPS_COP_0_WATCH_HI, 1); 245202031SimpMIPS_RDRW32_COP0_SEL(watchhi, MIPS_COP_0_WATCH_HI, 2); 246202031SimpMIPS_RDRW32_COP0_SEL(watchhi, MIPS_COP_0_WATCH_HI, 3); 247204635Sgnn 248204635SgnnMIPS_RDRW32_COP0_SEL(perfcnt, MIPS_COP_0_PERFCNT, 0); 249204635SgnnMIPS_RDRW32_COP0_SEL(perfcnt, MIPS_COP_0_PERFCNT, 1); 250204635SgnnMIPS_RDRW32_COP0_SEL(perfcnt, MIPS_COP_0_PERFCNT, 2); 251204635SgnnMIPS_RDRW32_COP0_SEL(perfcnt, MIPS_COP_0_PERFCNT, 3); 252204635Sgnn 253204635Sgnn 254178172Simp#undef MIPS_RDRW32_COP0 255178172Simp 256178172Simpstatic __inline register_t 257178172Simpintr_disable(void) 258178172Simp{ 259178172Simp register_t s; 260178172Simp 261178172Simp s = mips_rd_status(); 262178172Simp mips_wr_status(s & ~MIPS_SR_INT_IE); 263178172Simp 264178172Simp return (s); 265178172Simp} 266178172Simp 267178172Simpstatic __inline register_t 268178172Simpintr_enable(void) 269178172Simp{ 270178172Simp register_t s; 271178172Simp 272178172Simp s = mips_rd_status(); 273178172Simp mips_wr_status(s | MIPS_SR_INT_IE); 274178172Simp 275178172Simp return (s); 276178172Simp} 277178172Simp 278178172Simp#define intr_restore(s) mips_wr_status((s)) 279178172Simp 280178172Simpstatic __inline void 281178172Simpbreakpoint(void) 282178172Simp{ 283178172Simp __asm __volatile ("break"); 284178172Simp} 285178172Simp 286178172Simp#endif /* _KERNEL */ 287178172Simp 288178172Simp#define readb(va) (*(volatile uint8_t *) (va)) 289178172Simp#define readw(va) (*(volatile uint16_t *) (va)) 290178172Simp#define readl(va) (*(volatile uint32_t *) (va)) 291178172Simp 292178172Simp#define writeb(va, d) (*(volatile uint8_t *) (va) = (d)) 293178172Simp#define writew(va, d) (*(volatile uint16_t *) (va) = (d)) 294178172Simp#define writel(va, d) (*(volatile uint32_t *) (va) = (d)) 295178172Simp 296178172Simp/* 297178172Simp * I/O macros. 298178172Simp */ 299178172Simp 300178172Simp#define outb(a,v) (*(volatile unsigned char*)(a) = (v)) 301178172Simp#define out8(a,v) (*(volatile unsigned char*)(a) = (v)) 302178172Simp#define outw(a,v) (*(volatile unsigned short*)(a) = (v)) 303178172Simp#define out16(a,v) outw(a,v) 304178172Simp#define outl(a,v) (*(volatile unsigned int*)(a) = (v)) 305178172Simp#define out32(a,v) outl(a,v) 306178172Simp#define inb(a) (*(volatile unsigned char*)(a)) 307178172Simp#define in8(a) (*(volatile unsigned char*)(a)) 308178172Simp#define inw(a) (*(volatile unsigned short*)(a)) 309178172Simp#define in16(a) inw(a) 310178172Simp#define inl(a) (*(volatile unsigned int*)(a)) 311178172Simp#define in32(a) inl(a) 312178172Simp 313178172Simp#define out8rb(a,v) (*(volatile unsigned char*)(a) = (v)) 314178172Simp#define out16rb(a,v) (__out16rb((volatile uint16_t *)(a), v)) 315178172Simp#define out32rb(a,v) (__out32rb((volatile uint32_t *)(a), v)) 316178172Simp#define in8rb(a) (*(volatile unsigned char*)(a)) 317178172Simp#define in16rb(a) (__in16rb((volatile uint16_t *)(a))) 318178172Simp#define in32rb(a) (__in32rb((volatile uint32_t *)(a))) 319178172Simp 320178172Simp#define _swap_(x) (((x) >> 24) | ((x) << 24) | \ 321178172Simp (((x) >> 8) & 0xff00) | (((x) & 0xff00) << 8)) 322178172Simp 323178172Simpstatic __inline void __out32rb(volatile uint32_t *, uint32_t); 324178172Simpstatic __inline void __out16rb(volatile uint16_t *, uint16_t); 325178172Simpstatic __inline uint32_t __in32rb(volatile uint32_t *); 326178172Simpstatic __inline uint16_t __in16rb(volatile uint16_t *); 327178172Simp 328178172Simpstatic __inline void 329178172Simp__out32rb(volatile uint32_t *a, uint32_t v) 330178172Simp{ 331178172Simp uint32_t _v_ = v; 332178172Simp 333178172Simp _v_ = _swap_(_v_); 334178172Simp out32(a, _v_); 335178172Simp} 336178172Simp 337178172Simpstatic __inline void 338178172Simp__out16rb(volatile uint16_t *a, uint16_t v) 339178172Simp{ 340178172Simp uint16_t _v_; 341178172Simp 342178172Simp _v_ = ((v >> 8) & 0xff) | (v << 8); 343178172Simp out16(a, _v_); 344178172Simp} 345178172Simp 346178172Simpstatic __inline uint32_t 347178172Simp__in32rb(volatile uint32_t *a) 348178172Simp{ 349178172Simp uint32_t _v_; 350178172Simp 351178172Simp _v_ = in32(a); 352178172Simp _v_ = _swap_(_v_); 353178172Simp return _v_; 354178172Simp} 355178172Simp 356178172Simpstatic __inline uint16_t 357178172Simp__in16rb(volatile uint16_t *a) 358178172Simp{ 359178172Simp uint16_t _v_; 360178172Simp 361178172Simp _v_ = in16(a); 362178172Simp _v_ = ((_v_ >> 8) & 0xff) | (_v_ << 8); 363178172Simp return _v_; 364178172Simp} 365178172Simp 366178172Simpvoid insb(uint8_t *, uint8_t *,int); 367178172Simpvoid insw(uint16_t *, uint16_t *,int); 368178172Simpvoid insl(uint32_t *, uint32_t *,int); 369178172Simpvoid outsb(uint8_t *, const uint8_t *,int); 370178172Simpvoid outsw(uint16_t *, const uint16_t *,int); 371178172Simpvoid outsl(uint32_t *, const uint32_t *,int); 372178172Simpu_int loadandclear(volatile u_int *addr); 373178172Simp 374178172Simp#endif /* !_MACHINE_CPUFUNC_H_ */ 375