Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 | /* $Id: io.h,v 1.20 1999/05/14 07:23:18 davem Exp $ */ #ifndef __SPARC64_IO_H #define __SPARC64_IO_H #include <linux/kernel.h> #include <linux/types.h> #include <asm/page.h> /* IO address mapping routines need this */ #include <asm/system.h> #include <asm/asi.h> /* PC crapola... */ #define __SLOW_DOWN_IO do { } while (0) #define SLOW_DOWN_IO do { } while (0) #define PCI_DVMA_HASHSZ 256 extern unsigned long pci_dvma_offset; extern unsigned long pci_dvma_mask; extern unsigned long pci_dvma_v2p_hash[PCI_DVMA_HASHSZ]; extern unsigned long pci_dvma_p2v_hash[PCI_DVMA_HASHSZ]; #define pci_dvma_ahashfn(addr) (((addr) >> 24) & 0xff) extern __inline__ unsigned long virt_to_phys(volatile void *addr) { unsigned long vaddr = (unsigned long)addr; unsigned long off; /* Handle kernel variable pointers... */ if (vaddr < PAGE_OFFSET) vaddr += PAGE_OFFSET - (unsigned long)&empty_zero_page; off = pci_dvma_v2p_hash[pci_dvma_ahashfn(vaddr - PAGE_OFFSET)]; return vaddr + off; } extern __inline__ void *phys_to_virt(unsigned long addr) { unsigned long paddr = addr & 0xffffffffUL; unsigned long off; off = pci_dvma_p2v_hash[pci_dvma_ahashfn(paddr)]; return (void *)(paddr + off); } #define virt_to_bus virt_to_phys #define bus_to_virt phys_to_virt extern __inline__ unsigned long bus_dvma_to_mem(unsigned long vaddr) { return vaddr & pci_dvma_mask; } extern __inline__ unsigned int inb(unsigned long addr) { unsigned int ret; __asm__ __volatile__("lduba [%1] %2, %0" : "=r" (ret) : "r" (addr), "i" (ASI_PL)); return ret; } extern __inline__ unsigned int inw(unsigned long addr) { unsigned int ret; __asm__ __volatile__("lduha [%1] %2, %0" : "=r" (ret) : "r" (addr), "i" (ASI_PL)); return ret; } extern __inline__ unsigned int inl(unsigned long addr) { unsigned int ret; __asm__ __volatile__("lduwa [%1] %2, %0" : "=r" (ret) : "r" (addr), "i" (ASI_PL)); return ret; } extern __inline__ void outb(unsigned char b, unsigned long addr) { __asm__ __volatile__("stba %0, [%1] %2" : /* no outputs */ : "r" (b), "r" (addr), "i" (ASI_PL)); } extern __inline__ void outw(unsigned short w, unsigned long addr) { __asm__ __volatile__("stha %0, [%1] %2" : /* no outputs */ : "r" (w), "r" (addr), "i" (ASI_PL)); } extern __inline__ void outl(unsigned int l, unsigned long addr) { __asm__ __volatile__("stwa %0, [%1] %2" : /* no outputs */ : "r" (l), "r" (addr), "i" (ASI_PL)); } #define inb_p inb #define outb_p outb extern void outsb(unsigned long addr, const void *src, unsigned long count); extern void outsw(unsigned long addr, const void *src, unsigned long count); extern void outsl(unsigned long addr, const void *src, unsigned long count); extern void insb(unsigned long addr, void *dst, unsigned long count); extern void insw(unsigned long addr, void *dst, unsigned long count); extern void insl(unsigned long addr, void *dst, unsigned long count); /* Memory functions, same as I/O accesses on Ultra. */ #define readb(addr) inb((unsigned long)(addr)) #define readw(addr) inw((unsigned long)(addr)) #define readl(addr) inl((unsigned long)(addr)) #define writeb(b, addr) outb((b), (unsigned long)(addr)) #define writew(w, addr) outw((w), (unsigned long)(addr)) #define writel(l, addr) outl((l), (unsigned long)(addr)) /* * Memcpy to/from I/O space is just a regular memory operation on * Ultra as well. */ /* * FIXME: Write faster routines using ASL_*L for this. */ static inline void * memset_io(void *dst, int c, __kernel_size_t n) { char *d = dst; while (n--) *d++ = c; return dst; } static inline void * memcpy_fromio(void *dst, const void *src, __kernel_size_t n) { const char *s = src; char *d = dst; while (n--) *d++ = *s++; return dst; } static inline void * memcpy_toio(void *dst, const void *src, __kernel_size_t n) { const char *s = src; char *d = dst; while (n--) *d++ = *s++; return dst; } #if 0 /* XXX Not exactly, we need to use ASI_*L from/to the I/O end, * XXX so these are disabled until we code that stuff. */ #define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),((char *)(b)),(c),(d)) #endif static inline int check_signature(unsigned long io_addr, const unsigned char *signature, int length) { int retval = 0; do { if (readb(io_addr++) != *signature++) goto out; } while (--length); retval = 1; out: return retval; } /* * On the sparc we have the whole physical IO address space mapped at all * times, so ioremap() and iounmap() do not need to do anything. */ extern __inline__ void *ioremap(unsigned long offset, unsigned long size) { return __va(offset); } extern __inline__ void iounmap(void *addr) { } extern void sparc_ultra_mapioaddr(unsigned long physaddr, unsigned long virt_addr, int bus, int rdonly); extern void sparc_ultra_unmapioaddr(unsigned long virt_addr); extern __inline__ void mapioaddr(unsigned long physaddr, unsigned long virt_addr, int bus, int rdonly) { sparc_ultra_mapioaddr(physaddr, virt_addr, bus, rdonly); } extern __inline__ void unmapioaddr(unsigned long virt_addr) { sparc_ultra_unmapioaddr(virt_addr); } extern void *sparc_alloc_io(u32 pa, void *va, int sz, char *name, u32 io, int rdonly); extern void sparc_free_io (void *va, int sz); extern void *sparc_dvma_malloc (int sz, char *name, __u32 *dvma_addr); /* Nothing to do */ #define dma_cache_inv(_start,_size) do { } while (0) #define dma_cache_wback(_start,_size) do { } while (0) #define dma_cache_wback_inv(_start,_size) do { } while (0) #endif /* !(__SPARC64_IO_H) */ |