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 const volatile u8 *) (unsigned long)(addr)); __v; }) 21 #define in_be16(addr) \ 22 ({ u16 __v = (*(__force const volatile u16 *) (unsigned long)(addr)); __v; }) 23 #define in_be32(addr) \ 24 ({ u32 __v = (*(__force const volatile u32 *) (unsigned long)(addr)); __v; }) 25 #define in_le16(addr) \ 26 ({ u16 __v = le16_to_cpu(*(__force const volatile __le16 *) (unsigned long)(addr)); __v; }) 27 #define in_le32(addr) \ 28 ({ u32 __v = le32_to_cpu(*(__force const volatile __le32 *) (unsigned long)(addr)); __v; }) 29 30 #define out_8(addr,b) (void)((*(__force volatile u8 *) (unsigned long)(addr)) = (b)) 31 #define out_be16(addr,w) (void)((*(__force volatile u16 *) (unsigned long)(addr)) = (w)) 32 #define out_be32(addr,l) (void)((*(__force volatile u32 *) (unsigned long)(addr)) = (l)) 33 #define out_le16(addr,w) (void)((*(__force volatile __le16 *) (unsigned long)(addr)) = cpu_to_le16(w)) 34 #define out_le32(addr,l) (void)((*(__force volatile __le32 *) (unsigned long)(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 const volatile u16 *) (addr)); __v >>= 8; __v; }) 77 #define rom_in_be16(addr) \ 78 ({ u16 __v = (*(__force const volatile u16 *) (addr)); __v; }) 79 #define rom_in_le16(addr) \ 80 ({ u16 __v = le16_to_cpu(*(__force const volatile u16 *) (addr)); __v; }) 81 82 #define rom_out_8(addr, b) \ 83 (void)({u8 __maybe_unused __w, __v = (b); u32 _addr = ((u32) (addr)); \ 84 __w = ((*(__force volatile u8 *) ((_addr | 0x10000) + (__v<<1)))); }) 85 #define rom_out_be16(addr, w) \ 86 (void)({u16 __maybe_unused __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 (void)({u16 __maybe_unused __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(const volatile u8 __iomem *port, u8 *buf, 102 unsigned int len) 103 { 104 unsigned int i; 105 106 for (i = 0; i < len; i++) 107 *buf++ = in_8(port); 108 } 109 110 static inline void raw_outsb(volatile u8 __iomem *port, const u8 *buf, 111 unsigned int nr) 112 { 113 unsigned int tmp; 114 115 if (nr & 15) { 116 tmp = (nr & 15) - 1; 117 asm volatile ( 118 "1: moveb %0@+,%2@; dbra %1,1b" 119 : "=a" (buf), "=d" (tmp) 120 : "a" (port), "0" (buf), 121 "1" (tmp)); 122 } 123 if (nr >> 4) { 124 tmp = (nr >> 4) - 1; 125 asm volatile ( 126 "1: " 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 "moveb %0@+,%2@; " 143 "dbra %1,1b" 144 : "=a" (buf), "=d" (tmp) 145 : "a" (port), "0" (buf), 146 "1" (tmp)); 147 } 148 } 149 150 static inline void raw_insw(volatile const u16 __iomem *port, u16 *buf, unsigned int nr) 151 { 152 unsigned int tmp; 153 154 if (nr & 15) { 155 tmp = (nr & 15) - 1; 156 asm volatile ( 157 "1: movew %2@,%0@+; dbra %1,1b" 158 : "=a" (buf), "=d" (tmp) 159 : "a" (port), "0" (buf), 160 "1" (tmp)); 161 } 162 if (nr >> 4) { 163 tmp = (nr >> 4) - 1; 164 asm volatile ( 165 "1: " 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 "movew %2@,%0@+; " 182 "dbra %1,1b" 183 : "=a" (buf), "=d" (tmp) 184 : "a" (port), "0" (buf), 185 "1" (tmp)); 186 } 187 } 188 189 static inline void raw_outsw(volatile u16 __iomem *port, const u16 *buf, 190 unsigned int nr) 191 { 192 unsigned int tmp; 193 194 if (nr & 15) { 195 tmp = (nr & 15) - 1; 196 asm volatile ( 197 "1: movew %0@+,%2@; dbra %1,1b" 198 : "=a" (buf), "=d" (tmp) 199 : "a" (port), "0" (buf), 200 "1" (tmp)); 201 } 202 if (nr >> 4) { 203 tmp = (nr >> 4) - 1; 204 asm volatile ( 205 "1: " 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 "movew %0@+,%2@; " 222 "dbra %1,1b" 223 : "=a" (buf), "=d" (tmp) 224 : "a" (port), "0" (buf), 225 "1" (tmp)); 226 } 227 } 228 229 static inline void raw_insl(const volatile u32 __iomem *port, u32 *buf, unsigned int nr) 230 { 231 unsigned int tmp; 232 233 if (nr & 15) { 234 tmp = (nr & 15) - 1; 235 asm volatile ( 236 "1: movel %2@,%0@+; dbra %1,1b" 237 : "=a" (buf), "=d" (tmp) 238 : "a" (port), "0" (buf), 239 "1" (tmp)); 240 } 241 if (nr >> 4) { 242 tmp = (nr >> 4) - 1; 243 asm volatile ( 244 "1: " 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 "movel %2@,%0@+; " 261 "dbra %1,1b" 262 : "=a" (buf), "=d" (tmp) 263 : "a" (port), "0" (buf), 264 "1" (tmp)); 265 } 266 } 267 268 static inline void raw_outsl(volatile u32 __iomem *port, const u32 *buf, 269 unsigned int nr) 270 { 271 unsigned int tmp; 272 273 if (nr & 15) { 274 tmp = (nr & 15) - 1; 275 asm volatile ( 276 "1: movel %0@+,%2@; dbra %1,1b" 277 : "=a" (buf), "=d" (tmp) 278 : "a" (port), "0" (buf), 279 "1" (tmp)); 280 } 281 if (nr >> 4) { 282 tmp = (nr >> 4) - 1; 283 asm volatile ( 284 "1: " 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 "movel %0@+,%2@; " 301 "dbra %1,1b" 302 : "=a" (buf), "=d" (tmp) 303 : "a" (port), "0" (buf), 304 "1" (tmp)); 305 } 306 } 307 308 309 static inline void raw_insw_swapw(const volatile u16 __iomem *port, u16 *buf, 310 unsigned int nr) 311 { 312 if ((nr) % 8) 313 __asm__ __volatile__ 314 ("\tmovel %0,%/a0\n\t" 315 "movel %1,%/a1\n\t" 316 "movel %2,%/d6\n\t" 317 "subql #1,%/d6\n" 318 "1:\tmovew %/a0@,%/d0\n\t" 319 "rolw #8,%/d0\n\t" 320 "movew %/d0,%/a1@+\n\t" 321 "dbra %/d6,1b" 322 : 323 : "g" (port), "g" (buf), "g" (nr) 324 : "d0", "a0", "a1", "d6"); 325 else 326 __asm__ __volatile__ 327 ("movel %0,%/a0\n\t" 328 "movel %1,%/a1\n\t" 329 "movel %2,%/d6\n\t" 330 "lsrl #3,%/d6\n\t" 331 "subql #1,%/d6\n" 332 "1:\tmovew %/a0@,%/d0\n\t" 333 "rolw #8,%/d0\n\t" 334 "movew %/d0,%/a1@+\n\t" 335 "movew %/a0@,%/d0\n\t" 336 "rolw #8,%/d0\n\t" 337 "movew %/d0,%/a1@+\n\t" 338 "movew %/a0@,%/d0\n\t" 339 "rolw #8,%/d0\n\t" 340 "movew %/d0,%/a1@+\n\t" 341 "movew %/a0@,%/d0\n\t" 342 "rolw #8,%/d0\n\t" 343 "movew %/d0,%/a1@+\n\t" 344 "movew %/a0@,%/d0\n\t" 345 "rolw #8,%/d0\n\t" 346 "movew %/d0,%/a1@+\n\t" 347 "movew %/a0@,%/d0\n\t" 348 "rolw #8,%/d0\n\t" 349 "movew %/d0,%/a1@+\n\t" 350 "movew %/a0@,%/d0\n\t" 351 "rolw #8,%/d0\n\t" 352 "movew %/d0,%/a1@+\n\t" 353 "movew %/a0@,%/d0\n\t" 354 "rolw #8,%/d0\n\t" 355 "movew %/d0,%/a1@+\n\t" 356 "dbra %/d6,1b" 357 : 358 : "g" (port), "g" (buf), "g" (nr) 359 : "d0", "a0", "a1", "d6"); 360 } 361 362 static inline void raw_outsw_swapw(volatile u16 __iomem *port, const u16 *buf, 363 unsigned int nr) 364 { 365 if ((nr) % 8) 366 __asm__ __volatile__ 367 ("movel %0,%/a0\n\t" 368 "movel %1,%/a1\n\t" 369 "movel %2,%/d6\n\t" 370 "subql #1,%/d6\n" 371 "1:\tmovew %/a1@+,%/d0\n\t" 372 "rolw #8,%/d0\n\t" 373 "movew %/d0,%/a0@\n\t" 374 "dbra %/d6,1b" 375 : 376 : "g" (port), "g" (buf), "g" (nr) 377 : "d0", "a0", "a1", "d6"); 378 else 379 __asm__ __volatile__ 380 ("movel %0,%/a0\n\t" 381 "movel %1,%/a1\n\t" 382 "movel %2,%/d6\n\t" 383 "lsrl #3,%/d6\n\t" 384 "subql #1,%/d6\n" 385 "1:\tmovew %/a1@+,%/d0\n\t" 386 "rolw #8,%/d0\n\t" 387 "movew %/d0,%/a0@\n\t" 388 "movew %/a1@+,%/d0\n\t" 389 "rolw #8,%/d0\n\t" 390 "movew %/d0,%/a0@\n\t" 391 "movew %/a1@+,%/d0\n\t" 392 "rolw #8,%/d0\n\t" 393 "movew %/d0,%/a0@\n\t" 394 "movew %/a1@+,%/d0\n\t" 395 "rolw #8,%/d0\n\t" 396 "movew %/d0,%/a0@\n\t" 397 "movew %/a1@+,%/d0\n\t" 398 "rolw #8,%/d0\n\t" 399 "movew %/d0,%/a0@\n\t" 400 "movew %/a1@+,%/d0\n\t" 401 "rolw #8,%/d0\n\t" 402 "movew %/d0,%/a0@\n\t" 403 "movew %/a1@+,%/d0\n\t" 404 "rolw #8,%/d0\n\t" 405 "movew %/d0,%/a0@\n\t" 406 "movew %/a1@+,%/d0\n\t" 407 "rolw #8,%/d0\n\t" 408 "movew %/d0,%/a0@\n\t" 409 "dbra %/d6,1b" 410 : 411 : "g" (port), "g" (buf), "g" (nr) 412 : "d0", "a0", "a1", "d6"); 413 } 414 415 416 #if defined(CONFIG_ATARI_ROM_ISA) 417 static inline void raw_rom_insb(const volatile u8 __iomem *port, u8 *buf, 418 unsigned int len) 419 { 420 unsigned int i; 421 422 for (i = 0; i < len; i++) 423 *buf++ = rom_in_8(port); 424 } 425 426 static inline void raw_rom_outsb(volatile u8 __iomem *port, const u8 *buf, 427 unsigned int len) 428 { 429 unsigned int i; 430 431 for (i = 0; i < len; i++) 432 rom_out_8(port, *buf++); 433 } 434 435 static inline void raw_rom_insw(const volatile u16 __iomem *port, u16 *buf, 436 unsigned int nr) 437 { 438 unsigned int i; 439 440 for (i = 0; i < nr; i++) 441 *buf++ = rom_in_be16(port); 442 } 443 444 static inline void raw_rom_outsw(volatile u16 __iomem *port, const u16 *buf, 445 unsigned int nr) 446 { 447 unsigned int i; 448 449 for (i = 0; i < nr; i++) 450 rom_out_be16(port, *buf++); 451 } 452 453 static inline void raw_rom_insw_swapw(const volatile u16 __iomem *port, u16 *buf, 454 unsigned int nr) 455 { 456 unsigned int i; 457 458 for (i = 0; i < nr; i++) 459 *buf++ = rom_in_le16(port); 460 } 461 462 static inline void raw_rom_outsw_swapw(volatile u16 __iomem *port, const u16 *buf, 463 unsigned int nr) 464 { 465 unsigned int i; 466 467 for (i = 0; i < nr; i++) 468 rom_out_le16(port, *buf++); 469 } 470 #endif /* CONFIG_ATARI_ROM_ISA */ 471 472 #endif /* __KERNEL__ */ 473 474 #endif /* _RAW_IO_H */ 475