1/* 2 * linux/include/asm-arm/arch-rpc/io.h 3 * 4 * Copyright (C) 1997 Russell King 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * Modifications: 11 * 06-Dec-1997 RMK Created. 12 */ 13#ifndef __ASM_ARM_ARCH_IO_H 14#define __ASM_ARM_ARCH_IO_H 15 16#define IO_SPACE_LIMIT 0xffffffff 17 18/* 19 * GCC is totally crap at loading/storing data. We try to persuade it 20 * to do the right thing by using these whereever possible instead of 21 * the above. 22 */ 23#define __arch_base_getb(b,o) \ 24 ({ \ 25 unsigned int v, r = (b); \ 26 __asm__ __volatile__( \ 27 "ldrb %0, [%1, %2]" \ 28 : "=r" (v) \ 29 : "r" (r), "Ir" (o)); \ 30 v; \ 31 }) 32 33#define __arch_base_getl(b,o) \ 34 ({ \ 35 unsigned int v, r = (b); \ 36 __asm__ __volatile__( \ 37 "ldr %0, [%1, %2]" \ 38 : "=r" (v) \ 39 : "r" (r), "Ir" (o)); \ 40 v; \ 41 }) 42 43#define __arch_base_putb(v,b,o) \ 44 ({ \ 45 unsigned int r = (b); \ 46 __asm__ __volatile__( \ 47 "strb %0, [%1, %2]" \ 48 : \ 49 : "r" (v), "r" (r), "Ir" (o)); \ 50 }) 51 52#define __arch_base_putl(v,b,o) \ 53 ({ \ 54 unsigned int r = (b); \ 55 __asm__ __volatile__( \ 56 "str %0, [%1, %2]" \ 57 : \ 58 : "r" (v), "r" (r), "Ir" (o)); \ 59 }) 60 61/* 62 * We use two different types of addressing - PC style addresses, and ARM 63 * addresses. PC style accesses the PC hardware with the normal PC IO 64 * addresses, eg 0x3f8 for serial#1. ARM addresses are 0x80000000+ 65 * and are translated to the start of IO. Note that all addresses are 66 * shifted left! 67 */ 68#define __PORT_PCIO(x) (!((x) & 0x80000000)) 69 70/* 71 * Dynamic IO functions. 72 */ 73static inline void __outb (unsigned int value, unsigned int port) 74{ 75 unsigned long temp; 76 __asm__ __volatile__( 77 "tst %2, #0x80000000\n\t" 78 "mov %0, %4\n\t" 79 "addeq %0, %0, %3\n\t" 80 "strb %1, [%0, %2, lsl #2] @ outb" 81 : "=&r" (temp) 82 : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) 83 : "cc"); 84} 85 86static inline void __outw (unsigned int value, unsigned int port) 87{ 88 unsigned long temp; 89 __asm__ __volatile__( 90 "tst %2, #0x80000000\n\t" 91 "mov %0, %4\n\t" 92 "addeq %0, %0, %3\n\t" 93 "str %1, [%0, %2, lsl #2] @ outw" 94 : "=&r" (temp) 95 : "r" (value|value<<16), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) 96 : "cc"); 97} 98 99static inline void __outl (unsigned int value, unsigned int port) 100{ 101 unsigned long temp; 102 __asm__ __volatile__( 103 "tst %2, #0x80000000\n\t" 104 "mov %0, %4\n\t" 105 "addeq %0, %0, %3\n\t" 106 "str %1, [%0, %2, lsl #2] @ outl" 107 : "=&r" (temp) 108 : "r" (value), "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) 109 : "cc"); 110} 111 112#define DECLARE_DYN_IN(sz,fnsuffix,instr) \ 113static inline unsigned sz __in##fnsuffix (unsigned int port) \ 114{ \ 115 unsigned long temp, value; \ 116 __asm__ __volatile__( \ 117 "tst %2, #0x80000000\n\t" \ 118 "mov %0, %4\n\t" \ 119 "addeq %0, %0, %3\n\t" \ 120 "ldr" instr " %1, [%0, %2, lsl #2] @ in" #fnsuffix \ 121 : "=&r" (temp), "=r" (value) \ 122 : "r" (port), "Ir" (PCIO_BASE - IO_BASE), "Ir" (IO_BASE) \ 123 : "cc"); \ 124 return (unsigned sz)value; \ 125} 126 127static inline unsigned int __ioaddr (unsigned int port) \ 128{ \ 129 if (__PORT_PCIO(port)) \ 130 return (unsigned int)(PCIO_BASE + (port << 2)); \ 131 else \ 132 return (unsigned int)(IO_BASE + (port << 2)); \ 133} 134 135#define DECLARE_IO(sz,fnsuffix,instr) \ 136 DECLARE_DYN_IN(sz,fnsuffix,instr) 137 138DECLARE_IO(char,b,"b") 139DECLARE_IO(short,w,"") 140DECLARE_IO(int,l,"") 141 142#undef DECLARE_IO 143#undef DECLARE_DYN_IN 144 145/* 146 * Constant address IO functions 147 * 148 * These have to be macros for the 'J' constraint to work - 149 * +/-4096 immediate operand. 150 */ 151#define __outbc(value,port) \ 152({ \ 153 if (__PORT_PCIO((port))) \ 154 __asm__ __volatile__( \ 155 "strb %0, [%1, %2] @ outbc" \ 156 : : "r" (value), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 157 else \ 158 __asm__ __volatile__( \ 159 "strb %0, [%1, %2] @ outbc" \ 160 : : "r" (value), "r" (IO_BASE), "r" ((port) << 2)); \ 161}) 162 163#define __inbc(port) \ 164({ \ 165 unsigned char result; \ 166 if (__PORT_PCIO((port))) \ 167 __asm__ __volatile__( \ 168 "ldrb %0, [%1, %2] @ inbc" \ 169 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 170 else \ 171 __asm__ __volatile__( \ 172 "ldrb %0, [%1, %2] @ inbc" \ 173 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ 174 result; \ 175}) 176 177#define __outwc(value,port) \ 178({ \ 179 unsigned long v = value; \ 180 if (__PORT_PCIO((port))) \ 181 __asm__ __volatile__( \ 182 "str %0, [%1, %2] @ outwc" \ 183 : : "r" (v|v<<16), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 184 else \ 185 __asm__ __volatile__( \ 186 "str %0, [%1, %2] @ outwc" \ 187 : : "r" (v|v<<16), "r" (IO_BASE), "r" ((port) << 2)); \ 188}) 189 190#define __inwc(port) \ 191({ \ 192 unsigned short result; \ 193 if (__PORT_PCIO((port))) \ 194 __asm__ __volatile__( \ 195 "ldr %0, [%1, %2] @ inwc" \ 196 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 197 else \ 198 __asm__ __volatile__( \ 199 "ldr %0, [%1, %2] @ inwc" \ 200 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ 201 result & 0xffff; \ 202}) 203 204#define __outlc(value,port) \ 205({ \ 206 unsigned long v = value; \ 207 if (__PORT_PCIO((port))) \ 208 __asm__ __volatile__( \ 209 "str %0, [%1, %2] @ outlc" \ 210 : : "r" (v), "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 211 else \ 212 __asm__ __volatile__( \ 213 "str %0, [%1, %2] @ outlc" \ 214 : : "r" (v), "r" (IO_BASE), "r" ((port) << 2)); \ 215}) 216 217#define __inlc(port) \ 218({ \ 219 unsigned long result; \ 220 if (__PORT_PCIO((port))) \ 221 __asm__ __volatile__( \ 222 "ldr %0, [%1, %2] @ inlc" \ 223 : "=r" (result) : "r" (PCIO_BASE), "Jr" ((port) << 2)); \ 224 else \ 225 __asm__ __volatile__( \ 226 "ldr %0, [%1, %2] @ inlc" \ 227 : "=r" (result) : "r" (IO_BASE), "r" ((port) << 2)); \ 228 result; \ 229}) 230 231#define __ioaddrc(port) \ 232 (__PORT_PCIO((port)) ? PCIO_BASE + ((port) << 2) : IO_BASE + ((port) << 2)) 233 234#define inb(p) (__builtin_constant_p((p)) ? __inbc(p) : __inb(p)) 235#define inw(p) (__builtin_constant_p((p)) ? __inwc(p) : __inw(p)) 236#define inl(p) (__builtin_constant_p((p)) ? __inlc(p) : __inl(p)) 237#define outb(v,p) (__builtin_constant_p((p)) ? __outbc(v,p) : __outb(v,p)) 238#define outw(v,p) (__builtin_constant_p((p)) ? __outwc(v,p) : __outw(v,p)) 239#define outl(v,p) (__builtin_constant_p((p)) ? __outlc(v,p) : __outl(v,p)) 240#define __ioaddr(p) (__builtin_constant_p((p)) ? __ioaddr(p) : __ioaddrc(p)) 241/* the following macro is depreciated */ 242#define ioaddr(port) __ioaddr((port)) 243 244#define insb(p,d,l) __raw_readsb(__ioaddr(p),d,l) 245#define insw(p,d,l) __raw_readsw(__ioaddr(p),d,l) 246 247#define outsb(p,d,l) __raw_writesb(__ioaddr(p),d,l) 248#define outsw(p,d,l) __raw_writesw(__ioaddr(p),d,l) 249 250#define iomem_valid_addr(o,s) (1) 251#define iomem_to_phys(a) (a) 252 253#endif 254