1/* $Id: io.h,v 1.1.1.1 2008/10/15 03:29:18 james26_jang Exp $ */ 2#ifndef __SPARC64_IO_H 3#define __SPARC64_IO_H 4 5#include <linux/kernel.h> 6#include <linux/types.h> 7 8#include <asm/page.h> /* IO address mapping routines need this */ 9#include <asm/system.h> 10#include <asm/asi.h> 11 12/* PC crapola... */ 13#define __SLOW_DOWN_IO do { } while (0) 14#define SLOW_DOWN_IO do { } while (0) 15 16extern unsigned long virt_to_bus_not_defined_use_pci_map(volatile void *addr); 17#define virt_to_bus virt_to_bus_not_defined_use_pci_map 18extern unsigned long bus_to_virt_not_defined_use_pci_map(volatile void *addr); 19#define bus_to_virt bus_to_virt_not_defined_use_pci_map 20 21extern unsigned long phys_base; 22#define page_to_phys(page) ((((page) - mem_map) << PAGE_SHIFT)+phys_base) 23 24/* Different PCI controllers we support have their PCI MEM space 25 * mapped to an either 2GB (Psycho) or 4GB (Sabre) aligned area, 26 * so need to chop off the top 33 or 32 bits. 27 */ 28extern unsigned long pci_memspace_mask; 29 30#define bus_dvma_to_mem(__vaddr) ((__vaddr) & pci_memspace_mask) 31 32static __inline__ u8 inb(unsigned long addr) 33{ 34 u8 ret; 35 36 __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_inb */" 37 : "=r" (ret) 38 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); 39 40 return ret; 41} 42 43static __inline__ u16 inw(unsigned long addr) 44{ 45 u16 ret; 46 47 __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_inw */" 48 : "=r" (ret) 49 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); 50 51 return ret; 52} 53 54static __inline__ u32 inl(unsigned long addr) 55{ 56 u32 ret; 57 58 __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_inl */" 59 : "=r" (ret) 60 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); 61 62 return ret; 63} 64 65static __inline__ void outb(u8 b, unsigned long addr) 66{ 67 __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_outb */" 68 : /* no outputs */ 69 : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); 70} 71 72static __inline__ void outw(u16 w, unsigned long addr) 73{ 74 __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_outw */" 75 : /* no outputs */ 76 : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); 77} 78 79static __inline__ void outl(u32 l, unsigned long addr) 80{ 81 __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_outl */" 82 : /* no outputs */ 83 : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); 84} 85 86#define inb_p inb 87#define outb_p outb 88#define inw_p inw 89#define outw_p outw 90#define inl_p inl 91#define outl_p outl 92 93extern void outsb(unsigned long addr, const void *src, unsigned long count); 94extern void outsw(unsigned long addr, const void *src, unsigned long count); 95extern void outsl(unsigned long addr, const void *src, unsigned long count); 96extern void insb(unsigned long addr, void *dst, unsigned long count); 97extern void insw(unsigned long addr, void *dst, unsigned long count); 98extern void insl(unsigned long addr, void *dst, unsigned long count); 99 100/* Memory functions, same as I/O accesses on Ultra. */ 101static __inline__ u8 _readb(unsigned long addr) 102{ 103 u8 ret; 104 105 __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_readb */" 106 : "=r" (ret) 107 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); 108 109 return ret; 110} 111 112static __inline__ u16 _readw(unsigned long addr) 113{ 114 u16 ret; 115 116 __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_readw */" 117 : "=r" (ret) 118 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); 119 120 return ret; 121} 122 123static __inline__ u32 _readl(unsigned long addr) 124{ 125 u32 ret; 126 127 __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_readl */" 128 : "=r" (ret) 129 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); 130 131 return ret; 132} 133 134static __inline__ u64 _readq(unsigned long addr) 135{ 136 u64 ret; 137 138 __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_readq */" 139 : "=r" (ret) 140 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); 141 142 return ret; 143} 144 145static __inline__ void _writeb(u8 b, unsigned long addr) 146{ 147 __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_writeb */" 148 : /* no outputs */ 149 : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); 150} 151 152static __inline__ void _writew(u16 w, unsigned long addr) 153{ 154 __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_writew */" 155 : /* no outputs */ 156 : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); 157} 158 159static __inline__ void _writel(u32 l, unsigned long addr) 160{ 161 __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */" 162 : /* no outputs */ 163 : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); 164} 165 166static __inline__ void _writeq(u64 q, unsigned long addr) 167{ 168 __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_writeq */" 169 : /* no outputs */ 170 : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L)); 171} 172 173#define readb(__addr) (_readb((unsigned long)(__addr))) 174#define readw(__addr) (_readw((unsigned long)(__addr))) 175#define readl(__addr) (_readl((unsigned long)(__addr))) 176#define readq(__addr) (_readq((unsigned long)(__addr))) 177#define writeb(__b, __addr) (_writeb((u8)(__b), (unsigned long)(__addr))) 178#define writew(__w, __addr) (_writew((u16)(__w), (unsigned long)(__addr))) 179#define writel(__l, __addr) (_writel((u32)(__l), (unsigned long)(__addr))) 180#define writeq(__q, __addr) (_writeq((u64)(__q), (unsigned long)(__addr))) 181 182/* Now versions without byte-swapping. */ 183static __inline__ u8 _raw_readb(unsigned long addr) 184{ 185 u8 ret; 186 187 __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_raw_readb */" 188 : "=r" (ret) 189 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 190 191 return ret; 192} 193 194static __inline__ u16 _raw_readw(unsigned long addr) 195{ 196 u16 ret; 197 198 __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_raw_readw */" 199 : "=r" (ret) 200 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 201 202 return ret; 203} 204 205static __inline__ u32 _raw_readl(unsigned long addr) 206{ 207 u32 ret; 208 209 __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_raw_readl */" 210 : "=r" (ret) 211 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 212 213 return ret; 214} 215 216static __inline__ u64 _raw_readq(unsigned long addr) 217{ 218 u64 ret; 219 220 __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_raw_readq */" 221 : "=r" (ret) 222 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 223 224 return ret; 225} 226 227static __inline__ void _raw_writeb(u8 b, unsigned long addr) 228{ 229 __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_raw_writeb */" 230 : /* no outputs */ 231 : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 232} 233 234static __inline__ void _raw_writew(u16 w, unsigned long addr) 235{ 236 __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_raw_writew */" 237 : /* no outputs */ 238 : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 239} 240 241static __inline__ void _raw_writel(u32 l, unsigned long addr) 242{ 243 __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_raw_writel */" 244 : /* no outputs */ 245 : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 246} 247 248static __inline__ void _raw_writeq(u64 q, unsigned long addr) 249{ 250 __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_raw_writeq */" 251 : /* no outputs */ 252 : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 253} 254 255#define __raw_readb(__addr) (_raw_readb((unsigned long)(__addr))) 256#define __raw_readw(__addr) (_raw_readw((unsigned long)(__addr))) 257#define __raw_readl(__addr) (_raw_readl((unsigned long)(__addr))) 258#define __raw_readq(__addr) (_raw_readq((unsigned long)(__addr))) 259#define __raw_writeb(__b, __addr) (_raw_writeb((u8)(__b), (unsigned long)(__addr))) 260#define __raw_writew(__w, __addr) (_raw_writew((u16)(__w), (unsigned long)(__addr))) 261#define __raw_writel(__l, __addr) (_raw_writel((u32)(__l), (unsigned long)(__addr))) 262#define __raw_writeq(__q, __addr) (_raw_writeq((u64)(__q), (unsigned long)(__addr))) 263 264/* Valid I/O Space regions are anywhere, because each PCI bus supported 265 * can live in an arbitrary area of the physical address range. 266 */ 267#define IO_SPACE_LIMIT 0xffffffffffffffffUL 268 269/* Now, SBUS variants, only difference from PCI is that we do 270 * not use little-endian ASIs. 271 */ 272static __inline__ u8 _sbus_readb(unsigned long addr) 273{ 274 u8 ret; 275 276 __asm__ __volatile__("lduba\t[%1] %2, %0\t/* sbus_readb */" 277 : "=r" (ret) 278 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 279 280 return ret; 281} 282 283static __inline__ u16 _sbus_readw(unsigned long addr) 284{ 285 u16 ret; 286 287 __asm__ __volatile__("lduha\t[%1] %2, %0\t/* sbus_readw */" 288 : "=r" (ret) 289 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 290 291 return ret; 292} 293 294static __inline__ u32 _sbus_readl(unsigned long addr) 295{ 296 u32 ret; 297 298 __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* sbus_readl */" 299 : "=r" (ret) 300 : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 301 302 return ret; 303} 304 305static __inline__ void _sbus_writeb(u8 b, unsigned long addr) 306{ 307 __asm__ __volatile__("stba\t%r0, [%1] %2\t/* sbus_writeb */" 308 : /* no outputs */ 309 : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 310} 311 312static __inline__ void _sbus_writew(u16 w, unsigned long addr) 313{ 314 __asm__ __volatile__("stha\t%r0, [%1] %2\t/* sbus_writew */" 315 : /* no outputs */ 316 : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 317} 318 319static __inline__ void _sbus_writel(u32 l, unsigned long addr) 320{ 321 __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* sbus_writel */" 322 : /* no outputs */ 323 : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); 324} 325 326#define sbus_readb(__addr) (_sbus_readb((unsigned long)(__addr))) 327#define sbus_readw(__addr) (_sbus_readw((unsigned long)(__addr))) 328#define sbus_readl(__addr) (_sbus_readl((unsigned long)(__addr))) 329#define sbus_writeb(__b, __addr) (_sbus_writeb((__b), (unsigned long)(__addr))) 330#define sbus_writew(__w, __addr) (_sbus_writew((__w), (unsigned long)(__addr))) 331#define sbus_writel(__l, __addr) (_sbus_writel((__l), (unsigned long)(__addr))) 332 333static inline void *_sbus_memset_io(unsigned long dst, int c, __kernel_size_t n) 334{ 335 while(n--) { 336 sbus_writeb(c, dst); 337 dst++; 338 } 339 return (void *) dst; 340} 341 342#define sbus_memset_io(d,c,sz) \ 343 _sbus_memset_io((unsigned long)d,(int)c,(__kernel_size_t)sz) 344 345static inline void * 346_memset_io(void *dst, int c, __kernel_size_t n) 347{ 348 char *d = dst; 349 350 while (n--) { 351 writeb(c, d); 352 d++; 353 } 354 355 return dst; 356} 357 358#define memset_io(d,c,sz) \ 359 _memset_io((void *)d,(int)c,(__kernel_size_t)sz) 360 361static inline void * 362_memcpy_fromio(void *dst, unsigned long src, __kernel_size_t n) 363{ 364 char *d = dst; 365 366 while (n--) { 367 char tmp = readb(src); 368 *d++ = tmp; 369 src++; 370 } 371 372 return dst; 373} 374 375#define memcpy_fromio(d,s,sz) \ 376 _memcpy_fromio((void *)d,(unsigned long)s,(__kernel_size_t)sz) 377 378static inline void * 379_memcpy_toio(unsigned long dst, const void *src, __kernel_size_t n) 380{ 381 const char *s = src; 382 unsigned long d = dst; 383 384 while (n--) { 385 char tmp = *s++; 386 writeb(tmp, d); 387 d++; 388 } 389 return (void *)dst; 390} 391 392#define memcpy_toio(d,s,sz) \ 393 _memcpy_toio((unsigned long)d,(const void *)s,(__kernel_size_t)sz) 394 395static inline int check_signature(unsigned long io_addr, 396 const unsigned char *signature, 397 int length) 398{ 399 int retval = 0; 400 do { 401 if (readb(io_addr++) != *signature++) 402 goto out; 403 } while (--length); 404 retval = 1; 405out: 406 return retval; 407} 408 409#ifdef __KERNEL__ 410 411/* On sparc64 we have the whole physical IO address space accessible 412 * using physically addressed loads and stores, so this does nothing. 413 */ 414#define ioremap(__offset, __size) ((void *)(__offset)) 415#define ioremap_nocache(X,Y) ioremap((X),(Y)) 416#define iounmap(__addr) do { } while(0) 417 418/* Similarly for SBUS. */ 419#define sbus_ioremap(__res, __offset, __size, __name) \ 420({ unsigned long __ret; \ 421 __ret = (__res)->start + (((__res)->flags & 0x1ffUL) << 32UL); \ 422 __ret += (unsigned long) (__offset); \ 423 if (! request_region((__ret), (__size), (__name))) \ 424 __ret = 0UL; \ 425 __ret; \ 426}) 427 428#define sbus_iounmap(__addr, __size) \ 429 release_region((__addr), (__size)) 430 431/* Nothing to do */ 432 433#define dma_cache_inv(_start,_size) do { } while (0) 434#define dma_cache_wback(_start,_size) do { } while (0) 435#define dma_cache_wback_inv(_start,_size) do { } while (0) 436 437#endif 438 439#endif /* !(__SPARC64_IO_H) */ 440