1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * linux/include/asm-m68k/raw_io.h 4 * 5 * 10/20/00 RZ: - created from bits of io.h and ide.h to cleanup namespace 6 * 7 */ 8 9 #ifndef _RAW_IO_H 10 #define _RAW_IO_H 11 12 #ifdef __KERNEL__ 13 14 #include <asm/byteorder.h> 15 16 /* ++roman: The assignments to temp. vars avoid that gcc sometimes generates 17 * two accesses to memory, which may be undesirable for some devices. 18 */ 19 #define in_8(addr) \ 20 ({ u8 __v = (*(__force volatile u8 *) (addr)); __v; }) 21 #define in_be16(addr) \ 22 ({ u16 __v = (*(__force volatile u16 *) (addr)); __v; }) 23 #define in_be32(addr) \ 24 ({ u32 __v = (*(__force volatile u32 *) (addr)); __v; }) 25 #define in_le16(addr) \ 26 ({ u16 __v = le16_to_cpu(*(__force volatile __le16 *) (addr)); __v; }) 27 #define in_le32(addr) \ 28 ({ u32 __v = le32_to_cpu(*(__force volatile __le32 *) (addr)); __v; }) 29 30 #define out_8(addr,b) (void)((*(__force volatile u8 *) (addr)) = (b)) 31 #define out_be16(addr,w) (void)((*(__force volatile u16 *) (addr)) = (w)) 32 #define out_be32(addr,l) (void)((*(__force volatile u32 *) (addr)) = (l)) 33 #define out_le16(addr,w) (void)((*(__force volatile __le16 *) (addr)) = cpu_to_le16(w)) 34 #define out_le32(addr,l) (void)((*(__force volatile __le32 *) (addr)) = cpu_to_le32(l)) 35 36 #define raw_inb in_8 37 #define raw_inw in_be16 38 #define raw_inl in_be32 39 #define __raw_readb in_8 40 #define __raw_readw in_be16 41 #define __raw_readl in_be32 42 43 #define raw_outb(val,port) out_8((port),(val)) 44 #define raw_outw(val,port) out_be16((port),(val)) 45 #define raw_outl(val,port) out_be32((port),(val)) 46 #define __raw_writeb(val,addr) out_8((addr),(val)) 47 #define __raw_writew(val,addr) out_be16((addr),(val)) 48 #define __raw_writel(val,addr) out_be32((addr),(val)) 49 50 /* 51 * Atari ROM port (cartridge port) ISA adapter, used for the EtherNEC NE2000 52 * network card driver. 53 * The ISA adapter connects address lines A9-A13 to ISA address lines A0-A4, 54 * and hardwires the rest of the ISA addresses for a base address of 0x300. 55 * 56 * Data lines D8-D15 are connected to ISA data lines D0-D7 for reading. 57 * For writes, address lines A1-A8 are latched to ISA data lines D0-D7 58 * (meaning the bit pattern on A1-A8 can be read back as byte). 59 * 60 * Read and write operations are distinguished by the base address used: 61 * reads are from the ROM A side range, writes are through the B side range 62 * addresses (A side base + 0x10000). 63 * 64 * Reads and writes are byte only. 65 * 66 * 16 bit reads and writes are necessary for the NetUSBee adapter's USB 67 * chipset - 16 bit words are read straight off the ROM port while 16 bit 68 * reads are split into two byte writes. The low byte is latched to the 69 * NetUSBee buffer by a read from the _read_ window (with the data pattern 70 * asserted as A1-A8 address pattern). The high byte is then written to the 71 * write range as usual, completing the write cycle. 72 */ 73 74 #if defined(CONFIG_ATARI_ROM_ISA) 75 #define rom_in_8(addr) \ 76 ({ u16 __v = (*(__force volatile u16 *) (addr)); __v >>= 8; __v; }) 77 #define rom_in_be16(addr) \ 78 ({ u16 __v = (*(__force volatile u16 *) (addr)); __v; }) 79 #define rom_in_le16(addr) \ 80 ({ u16 __v = le16_to_cpu(*(__force volatile u16 *) (addr)); __v; }) 81 82 #define rom_out_8(addr, b) \ 83 ({u8 __w, __v = (b); u32 _addr = ((u32) (addr)); \ 84 __w = ((*(__force volatile u8 *) ((_addr | 0x10000) + (__v<<1)))); }) 85 #define rom_out_be16(addr, w) \ 86 ({u16 __w, __v = (w); u32 _addr = ((u32) (addr)); \ 87 __w = ((*(__force volatile u16 *) ((_addr & 0xFFFF0000UL) + ((__v & 0xFF)<<1)))); \ 88 __w = ((*(__force volatile u16 *) ((_addr | 0x10000) + ((__v >> 8)<<1)))); }) 89 #define rom_out_le16(addr, w) \ 90 ({u16 __w, __v = (w); u32 _addr = ((u32) (addr)); \ 91 __w = ((*(__force volatile u16 *) ((_addr & 0xFFFF0000UL) + ((__v >> 8)<<1)))); \ 92 __w = ((*(__force volatile u16 *) ((_addr | 0x10000) + ((__v & 0xFF)<<1)))); }) 93 94 #define raw_rom_inb rom_in_8 95 #define raw_rom_inw rom_in_be16 96 97 #define raw_rom_outb(val, port) rom_out_8((port), (val)) 98 #define raw_rom_outw(val, port) rom_out_be16((port), (val)) 99 #endif /* CONFIG_ATARI_ROM_ISA */ 100 101 static inline void raw_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len) 102 { 103 unsigned int i; 104 105 for (i = 0; i < len; i++) 106 *buf++ = in_8(port); 107 } 108 109 static inline void raw_outsb(volatile u8 __iomem *port, const u8 *buf, 110 unsigned int nr) 111 { 112 unsigned int tmp; 113 114 if (nr & 15) { 115 tmp = (nr & 15) - 1; 116 asm volatile ( 117 "1: moveb %0@+,%2@; dbra %1,1b" 118 : "=a" (buf), "=d" (tmp) 119 : "a" (port), "0" (buf), 120 "1" (tmp)); 121 } 122 if (nr >> 4) { 123 tmp = (nr >> 4) - 1; 124 asm volatile ( 125 "1: " 126 "moveb %0@+,%2@; " 127 "moveb %0@+,%2@; " 128 "moveb %0@+,%2@; " 129 "moveb %0@+,%2@; " 130 "moveb %0@+,%2@; " 131 "moveb %0@+,%2@; " 132 "moveb %0@+,%2@; " 133 "moveb %0@+,%2@; " 134 "moveb %0@+,%2@; " 135 "moveb %0@+,%2@; " 136 "moveb %0@+,%2@; " 137 "moveb %0@+,%2@; " 138 "moveb %0@+,%2@; " 139 "moveb %0@+,%2@; " 140 "moveb %0@+,%2@; " 141 "moveb %0@+,%2@; " 142 "dbra %1,1b" 143 : "=a" (buf), "=d" (tmp) 144 : "a" (port), "0" (buf), 145 "1" (tmp)); 146 } 147 } 148 149 static inline void raw_insw(volatile u16 __iomem *port, u16 *buf, unsigned int nr) 150 { 151 unsigned int tmp; 152 153 if (nr & 15) { 154 tmp = (nr & 15) - 1; 155 asm volatile ( 156 "1: movew %2@,%0@+; dbra %1,1b" 157 : "=a" (buf), "=d" (tmp) 158 : "a" (port), "0" (buf), 159 "1" (tmp)); 160 } 161 if (nr >> 4) { 162 tmp = (nr >> 4) - 1; 163 asm volatile ( 164 "1: " 165 "movew %2@,%0@+; " 166 "movew %2@,%0@+; " 167 "movew %2@,%0@+; " 168 "movew %2@,%0@+; " 169 "movew %2@,%0@+; " 170 "movew %2@,%0@+; " 171 "movew %2@,%0@+; " 172 "movew %2@,%0@+; " 173 "movew %2@,%0@+; " 174 "movew %2@,%0@+; " 175 "movew %2@,%0@+; " 176 "movew %2@,%0@+; " 177 "movew %2@,%0@+; " 178 "movew %2@,%0@+; " 179 "movew %2@,%0@+; " 180 "movew %2@,%0@+; " 181 "dbra %1,1b" 182 : "=a" (buf), "=d" (tmp) 183 : "a" (port), "0" (buf), 184 "1" (tmp)); 185 } 186 } 187 188 static inline void raw_outsw(volatile u16 __iomem *port, const u16 *buf, 189 unsigned int nr) 190 { 191 unsigned int tmp; 192 193 if (nr & 15) { 194 tmp = (nr & 15) - 1; 195 asm volatile ( 196 "1: movew %0@+,%2@; dbra %1,1b" 197 : "=a" (buf), "=d" (tmp) 198 : "a" (port), "0" (buf), 199 "1" (tmp)); 200 } 201 if (nr >> 4) { 202 tmp = (nr >> 4) - 1; 203 asm volatile ( 204 "1: " 205 "movew %0@+,%2@; " 206 "movew %0@+,%2@; " 207 "movew %0@+,%2@; " 208 "movew %0@+,%2@; " 209 "movew %0@+,%2@; " 210 "movew %0@+,%2@; " 211 "movew %0@+,%2@; " 212 "movew %0@+,%2@; " 213 "movew %0@+,%2@; " 214 "movew %0@+,%2@; " 215 "movew %0@+,%2@; " 216 "movew %0@+,%2@; " 217 "movew %0@+,%2@; " 218 "movew %0@+,%2@; " 219 "movew %0@+,%2@; " 220 "movew %0@+,%2@; " 221 "dbra %1,1b" 222 : "=a" (buf), "=d" (tmp) 223 : "a" (port), "0" (buf), 224 "1" (tmp)); 225 } 226 } 227 228 static inline void raw_insl(volatile u32 __iomem *port, u32 *buf, unsigned int nr) 229 { 230 unsigned int tmp; 231 232 if (nr & 15) { 233 tmp = (nr & 15) - 1; 234 asm volatile ( 235 "1: movel %2@,%0@+; dbra %1,1b" 236 : "=a" (buf), "=d" (tmp) 237 : "a" (port), "0" (buf), 238 "1" (tmp)); 239 } 240 if (nr >> 4) { 241 tmp = (nr >> 4) - 1; 242 asm volatile ( 243 "1: " 244 "movel %2@,%0@+; " 245 "movel %2@,%0@+; " 246 "movel %2@,%0@+; " 247 "movel %2@,%0@+; " 248 "movel %2@,%0@+; " 249 "movel %2@,%0@+; " 250 "movel %2@,%0@+; " 251 "movel %2@,%0@+; " 252 "movel %2@,%0@+; " 253 "movel %2@,%0@+; " 254 "movel %2@,%0@+; " 255 "movel %2@,%0@+; " 256 "movel %2@,%0@+; " 257 "movel %2@,%0@+; " 258 "movel %2@,%0@+; " 259 "movel %2@,%0@+; " 260 "dbra %1,1b" 261 : "=a" (buf), "=d" (tmp) 262 : "a" (port), "0" (buf), 263 "1" (tmp)); 264 } 265 } 266 267 static inline void raw_outsl(volatile u32 __iomem *port, const u32 *buf, 268 unsigned int nr) 269 { 270 unsigned int tmp; 271 272 if (nr & 15) { 273 tmp = (nr & 15) - 1; 274 asm volatile ( 275 "1: movel %0@+,%2@; dbra %1,1b" 276 : "=a" (buf), "=d" (tmp) 277 : "a" (port), "0" (buf), 278 "1" (tmp)); 279 } 280 if (nr >> 4) { 281 tmp = (nr >> 4) - 1; 282 asm volatile ( 283 "1: " 284 "movel %0@+,%2@; " 285 "movel %0@+,%2@; " 286 "movel %0@+,%2@; " 287 "movel %0@+,%2@; " 288 "movel %0@+,%2@; " 289 "movel %0@+,%2@; " 290 "movel %0@+,%2@; " 291 "movel %0@+,%2@; " 292 "movel %0@+,%2@; " 293 "movel %0@+,%2@; " 294 "movel %0@+,%2@; " 295 "movel %0@+,%2@; " 296 "movel %0@+,%2@; " 297 "movel %0@+,%2@; " 298 "movel %0@+,%2@; " 299 "movel %0@+,%2@; " 300 "dbra %1,1b" 301 : "=a" (buf), "=d" (tmp) 302 : "a" (port), "0" (buf), 303 "1" (tmp)); 304 } 305 } 306 307 308 static inline void raw_insw_swapw(volatile u16 __iomem *port, u16 *buf, 309 unsigned int nr) 310 { 311 if ((nr) % 8) 312 __asm__ __volatile__ 313 ("\tmovel %0,%/a0\n\t" 314 "movel %1,%/a1\n\t" 315 "movel %2,%/d6\n\t" 316 "subql #1,%/d6\n" 317 "1:\tmovew %/a0@,%/d0\n\t" 318 "rolw #8,%/d0\n\t" 319 "movew %/d0,%/a1@+\n\t" 320 "dbra %/d6,1b" 321 : 322 : "g" (port), "g" (buf), "g" (nr) 323 : "d0", "a0", "a1", "d6"); 324 else 325 __asm__ __volatile__ 326 ("movel %0,%/a0\n\t" 327 "movel %1,%/a1\n\t" 328 "movel %2,%/d6\n\t" 329 "lsrl #3,%/d6\n\t" 330 "subql #1,%/d6\n" 331 "1:\tmovew %/a0@,%/d0\n\t" 332 "rolw #8,%/d0\n\t" 333 "movew %/d0,%/a1@+\n\t" 334 "movew %/a0@,%/d0\n\t" 335 "rolw #8,%/d0\n\t" 336 "movew %/d0,%/a1@+\n\t" 337 "movew %/a0@,%/d0\n\t" 338 "rolw #8,%/d0\n\t" 339 "movew %/d0,%/a1@+\n\t" 340 "movew %/a0@,%/d0\n\t" 341 "rolw #8,%/d0\n\t" 342 "movew %/d0,%/a1@+\n\t" 343 "movew %/a0@,%/d0\n\t" 344 "rolw #8,%/d0\n\t" 345 "movew %/d0,%/a1@+\n\t" 346 "movew %/a0@,%/d0\n\t" 347 "rolw #8,%/d0\n\t" 348 "movew %/d0,%/a1@+\n\t" 349 "movew %/a0@,%/d0\n\t" 350 "rolw #8,%/d0\n\t" 351 "movew %/d0,%/a1@+\n\t" 352 "movew %/a0@,%/d0\n\t" 353 "rolw #8,%/d0\n\t" 354 "movew %/d0,%/a1@+\n\t" 355 "dbra %/d6,1b" 356 : 357 : "g" (port), "g" (buf), "g" (nr) 358 : "d0", "a0", "a1", "d6"); 359 } 360 361 static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf, 362 unsigned int nr) 363 { 364 if ((nr) % 8) 365 __asm__ __volatile__ 366 ("movel %0,%/a0\n\t" 367 "movel %1,%/a1\n\t" 368 "movel %2,%/d6\n\t" 369 "subql #1,%/d6\n" 370 "1:\tmovew %/a1@+,%/d0\n\t" 371 "rolw #8,%/d0\n\t" 372 "movew %/d0,%/a0@\n\t" 373 "dbra %/d6,1b" 374 : 375 : "g" (port), "g" (buf), "g" (nr) 376 : "d0", "a0", "a1", "d6"); 377 else 378 __asm__ __volatile__ 379 ("movel %0,%/a0\n\t" 380 "movel %1,%/a1\n\t" 381 "movel %2,%/d6\n\t" 382 "lsrl #3,%/d6\n\t" 383 "subql #1,%/d6\n" 384 "1:\tmovew %/a1@+,%/d0\n\t" 385 "rolw #8,%/d0\n\t" 386 "movew %/d0,%/a0@\n\t" 387 "movew %/a1@+,%/d0\n\t" 388 "rolw #8,%/d0\n\t" 389 "movew %/d0,%/a0@\n\t" 390 "movew %/a1@+,%/d0\n\t" 391 "rolw #8,%/d0\n\t" 392 "movew %/d0,%/a0@\n\t" 393 "movew %/a1@+,%/d0\n\t" 394 "rolw #8,%/d0\n\t" 395 "movew %/d0,%/a0@\n\t" 396 "movew %/a1@+,%/d0\n\t" 397 "rolw #8,%/d0\n\t" 398 "movew %/d0,%/a0@\n\t" 399 "movew %/a1@+,%/d0\n\t" 400 "rolw #8,%/d0\n\t" 401 "movew %/d0,%/a0@\n\t" 402 "movew %/a1@+,%/d0\n\t" 403 "rolw #8,%/d0\n\t" 404 "movew %/d0,%/a0@\n\t" 405 "movew %/a1@+,%/d0\n\t" 406 "rolw #8,%/d0\n\t" 407 "movew %/d0,%/a0@\n\t" 408 "dbra %/d6,1b" 409 : 410 : "g" (port), "g" (buf), "g" (nr) 411 : "d0", "a0", "a1", "d6"); 412 } 413 414 415 #if defined(CONFIG_ATARI_ROM_ISA) 416 static inline void raw_rom_insb(volatile u8 __iomem *port, u8 *buf, unsigned int len) 417 { 418 unsigned int i; 419 420 for (i = 0; i < len; i++) 421 *buf++ = rom_in_8(port); 422 } 423 424 static inline void raw_rom_outsb(volatile u8 __iomem *port, const u8 *buf, 425 unsigned int len) 426 { 427 unsigned int i; 428 429 for (i = 0; i < len; i++) 430 rom_out_8(port, *buf++); 431 } 432 433 static inline void raw_rom_insw(volatile u16 __iomem *port, u16 *buf, 434 unsigned int nr) 435 { 436 unsigned int i; 437 438 for (i = 0; i < nr; i++) 439 *buf++ = rom_in_be16(port); 440 } 441 442 static inline void raw_rom_outsw(volatile u16 __iomem *port, const u16 *buf, 443 unsigned int nr) 444 { 445 unsigned int i; 446 447 for (i = 0; i < nr; i++) 448 rom_out_be16(port, *buf++); 449 } 450 451 static inline void raw_rom_insw_swapw(volatile u16 __iomem *port, u16 *buf, 452 unsigned int nr) 453 { 454 unsigned int i; 455 456 for (i = 0; i < nr; i++) 457 *buf++ = rom_in_le16(port); 458 } 459 460 static inline void raw_rom_outsw_swapw(volatile u16 __iomem *port, const u16 *buf, 461 unsigned int nr) 462 { 463 unsigned int i; 464 465 for (i = 0; i < nr; i++) 466 rom_out_le16(port, *buf++); 467 } 468 #endif /* CONFIG_ATARI_ROM_ISA */ 469 470 #endif /* __KERNEL__ */ 471 472 #endif /* _RAW_IO_H */ 473