1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * iomap.c - Implement iomap interface for PA-RISC 4 * Copyright (c) 2004 Matthew Wilcox 5 */ 6 7 #include <linux/ioport.h> 8 #include <linux/pci.h> 9 #include <linux/export.h> 10 #include <asm/io.h> 11 12 /* 13 * The iomap space on 32-bit PA-RISC is intended to look like this: 14 * 00000000-7fffffff virtual mapped IO 15 * 80000000-8fffffff ISA/EISA port space that can't be virtually mapped 16 * 90000000-9fffffff Dino port space 17 * a0000000-afffffff Astro port space 18 * b0000000-bfffffff PAT port space 19 * c0000000-cfffffff non-swapped memory IO 20 * f0000000-ffffffff legacy IO memory pointers 21 * 22 * For the moment, here's what it looks like: 23 * 80000000-8fffffff All ISA/EISA port space 24 * f0000000-ffffffff legacy IO memory pointers 25 * 26 * On 64-bit, everything is extended, so: 27 * 8000000000000000-8fffffffffffffff All ISA/EISA port space 28 * f000000000000000-ffffffffffffffff legacy IO memory pointers 29 */ 30 31 /* 32 * Technically, this should be 'if (VMALLOC_START < addr < VMALLOC_END), 33 * but that's slow and we know it'll be within the first 2GB. 34 */ 35 #ifdef CONFIG_64BIT 36 #define INDIRECT_ADDR(addr) (((unsigned long)(addr) & 1UL<<63) != 0) 37 #define ADDR_TO_REGION(addr) (((unsigned long)addr >> 60) & 7) 38 #define IOPORT_MAP_BASE (8UL << 60) 39 #else 40 #define INDIRECT_ADDR(addr) (((unsigned long)(addr) & 1UL<<31) != 0) 41 #define ADDR_TO_REGION(addr) (((unsigned long)addr >> 28) & 7) 42 #define IOPORT_MAP_BASE (8UL << 28) 43 #endif 44 45 struct iomap_ops { 46 unsigned int (*read8)(const void __iomem *); 47 unsigned int (*read16)(const void __iomem *); 48 unsigned int (*read16be)(const void __iomem *); 49 unsigned int (*read32)(const void __iomem *); 50 unsigned int (*read32be)(const void __iomem *); 51 u64 (*read64)(const void __iomem *); 52 u64 (*read64be)(const void __iomem *); 53 void (*write8)(u8, void __iomem *); 54 void (*write16)(u16, void __iomem *); 55 void (*write16be)(u16, void __iomem *); 56 void (*write32)(u32, void __iomem *); 57 void (*write32be)(u32, void __iomem *); 58 void (*write64)(u64, void __iomem *); 59 void (*write64be)(u64, void __iomem *); 60 void (*read8r)(const void __iomem *, void *, unsigned long); 61 void (*read16r)(const void __iomem *, void *, unsigned long); 62 void (*read32r)(const void __iomem *, void *, unsigned long); 63 void (*write8r)(void __iomem *, const void *, unsigned long); 64 void (*write16r)(void __iomem *, const void *, unsigned long); 65 void (*write32r)(void __iomem *, const void *, unsigned long); 66 }; 67 68 /* Generic ioport ops. To be replaced later by specific dino/elroy/wax code */ 69 70 #define ADDR2PORT(addr) ((unsigned long __force)(addr) & 0xffffff) 71 72 static unsigned int ioport_read8(const void __iomem *addr) 73 { 74 return inb(ADDR2PORT(addr)); 75 } 76 77 static unsigned int ioport_read16(const void __iomem *addr) 78 { 79 return inw(ADDR2PORT(addr)); 80 } 81 82 static unsigned int ioport_read32(const void __iomem *addr) 83 { 84 return inl(ADDR2PORT(addr)); 85 } 86 87 static void ioport_write8(u8 datum, void __iomem *addr) 88 { 89 outb(datum, ADDR2PORT(addr)); 90 } 91 92 static void ioport_write16(u16 datum, void __iomem *addr) 93 { 94 outw(datum, ADDR2PORT(addr)); 95 } 96 97 static void ioport_write32(u32 datum, void __iomem *addr) 98 { 99 outl(datum, ADDR2PORT(addr)); 100 } 101 102 static void ioport_read8r(const void __iomem *addr, void *dst, unsigned long count) 103 { 104 insb(ADDR2PORT(addr), dst, count); 105 } 106 107 static void ioport_read16r(const void __iomem *addr, void *dst, unsigned long count) 108 { 109 insw(ADDR2PORT(addr), dst, count); 110 } 111 112 static void ioport_read32r(const void __iomem *addr, void *dst, unsigned long count) 113 { 114 insl(ADDR2PORT(addr), dst, count); 115 } 116 117 static void ioport_write8r(void __iomem *addr, const void *s, unsigned long n) 118 { 119 outsb(ADDR2PORT(addr), s, n); 120 } 121 122 static void ioport_write16r(void __iomem *addr, const void *s, unsigned long n) 123 { 124 outsw(ADDR2PORT(addr), s, n); 125 } 126 127 static void ioport_write32r(void __iomem *addr, const void *s, unsigned long n) 128 { 129 outsl(ADDR2PORT(addr), s, n); 130 } 131 132 static const struct iomap_ops ioport_ops = { 133 .read8 = ioport_read8, 134 .read16 = ioport_read16, 135 .read16be = ioport_read16, 136 .read32 = ioport_read32, 137 .read32be = ioport_read32, 138 .write8 = ioport_write8, 139 .write16 = ioport_write16, 140 .write16be = ioport_write16, 141 .write32 = ioport_write32, 142 .write32be = ioport_write32, 143 .read8r = ioport_read8r, 144 .read16r = ioport_read16r, 145 .read32r = ioport_read32r, 146 .write8r = ioport_write8r, 147 .write16r = ioport_write16r, 148 .write32r = ioport_write32r, 149 }; 150 151 /* Legacy I/O memory ops */ 152 153 static unsigned int iomem_read8(const void __iomem *addr) 154 { 155 return readb(addr); 156 } 157 158 static unsigned int iomem_read16(const void __iomem *addr) 159 { 160 return readw(addr); 161 } 162 163 static unsigned int iomem_read16be(const void __iomem *addr) 164 { 165 return __raw_readw(addr); 166 } 167 168 static unsigned int iomem_read32(const void __iomem *addr) 169 { 170 return readl(addr); 171 } 172 173 static unsigned int iomem_read32be(const void __iomem *addr) 174 { 175 return __raw_readl(addr); 176 } 177 178 static u64 iomem_read64(const void __iomem *addr) 179 { 180 return readq(addr); 181 } 182 183 static u64 iomem_read64be(const void __iomem *addr) 184 { 185 return __raw_readq(addr); 186 } 187 188 static void iomem_write8(u8 datum, void __iomem *addr) 189 { 190 writeb(datum, addr); 191 } 192 193 static void iomem_write16(u16 datum, void __iomem *addr) 194 { 195 writew(datum, addr); 196 } 197 198 static void iomem_write16be(u16 datum, void __iomem *addr) 199 { 200 __raw_writew(datum, addr); 201 } 202 203 static void iomem_write32(u32 datum, void __iomem *addr) 204 { 205 writel(datum, addr); 206 } 207 208 static void iomem_write32be(u32 datum, void __iomem *addr) 209 { 210 __raw_writel(datum, addr); 211 } 212 213 static void iomem_write64(u64 datum, void __iomem *addr) 214 { 215 writel(datum, addr); 216 } 217 218 static void iomem_write64be(u64 datum, void __iomem *addr) 219 { 220 __raw_writel(datum, addr); 221 } 222 223 static void iomem_read8r(const void __iomem *addr, void *dst, unsigned long count) 224 { 225 while (count--) { 226 *(u8 *)dst = __raw_readb(addr); 227 dst++; 228 } 229 } 230 231 static void iomem_read16r(const void __iomem *addr, void *dst, unsigned long count) 232 { 233 while (count--) { 234 *(u16 *)dst = __raw_readw(addr); 235 dst += 2; 236 } 237 } 238 239 static void iomem_read32r(const void __iomem *addr, void *dst, unsigned long count) 240 { 241 while (count--) { 242 *(u32 *)dst = __raw_readl(addr); 243 dst += 4; 244 } 245 } 246 247 static void iomem_write8r(void __iomem *addr, const void *s, unsigned long n) 248 { 249 while (n--) { 250 __raw_writeb(*(u8 *)s, addr); 251 s++; 252 } 253 } 254 255 static void iomem_write16r(void __iomem *addr, const void *s, unsigned long n) 256 { 257 while (n--) { 258 __raw_writew(*(u16 *)s, addr); 259 s += 2; 260 } 261 } 262 263 static void iomem_write32r(void __iomem *addr, const void *s, unsigned long n) 264 { 265 while (n--) { 266 __raw_writel(*(u32 *)s, addr); 267 s += 4; 268 } 269 } 270 271 static const struct iomap_ops iomem_ops = { 272 .read8 = iomem_read8, 273 .read16 = iomem_read16, 274 .read16be = iomem_read16be, 275 .read32 = iomem_read32, 276 .read32be = iomem_read32be, 277 .read64 = iomem_read64, 278 .read64be = iomem_read64be, 279 .write8 = iomem_write8, 280 .write16 = iomem_write16, 281 .write16be = iomem_write16be, 282 .write32 = iomem_write32, 283 .write32be = iomem_write32be, 284 .write64 = iomem_write64, 285 .write64be = iomem_write64be, 286 .read8r = iomem_read8r, 287 .read16r = iomem_read16r, 288 .read32r = iomem_read32r, 289 .write8r = iomem_write8r, 290 .write16r = iomem_write16r, 291 .write32r = iomem_write32r, 292 }; 293 294 static const struct iomap_ops *iomap_ops[8] = { 295 [0] = &ioport_ops, 296 [7] = &iomem_ops 297 }; 298 299 300 unsigned int ioread8(const void __iomem *addr) 301 { 302 if (unlikely(INDIRECT_ADDR(addr))) 303 return iomap_ops[ADDR_TO_REGION(addr)]->read8(addr); 304 return *((u8 *)addr); 305 } 306 307 unsigned int ioread16(const void __iomem *addr) 308 { 309 if (unlikely(INDIRECT_ADDR(addr))) 310 return iomap_ops[ADDR_TO_REGION(addr)]->read16(addr); 311 return le16_to_cpup((u16 *)addr); 312 } 313 314 unsigned int ioread16be(const void __iomem *addr) 315 { 316 if (unlikely(INDIRECT_ADDR(addr))) 317 return iomap_ops[ADDR_TO_REGION(addr)]->read16be(addr); 318 return *((u16 *)addr); 319 } 320 321 unsigned int ioread32(const void __iomem *addr) 322 { 323 if (unlikely(INDIRECT_ADDR(addr))) 324 return iomap_ops[ADDR_TO_REGION(addr)]->read32(addr); 325 return le32_to_cpup((u32 *)addr); 326 } 327 328 unsigned int ioread32be(const void __iomem *addr) 329 { 330 if (unlikely(INDIRECT_ADDR(addr))) 331 return iomap_ops[ADDR_TO_REGION(addr)]->read32be(addr); 332 return *((u32 *)addr); 333 } 334 335 u64 ioread64(const void __iomem *addr) 336 { 337 if (unlikely(INDIRECT_ADDR(addr))) 338 return iomap_ops[ADDR_TO_REGION(addr)]->read64(addr); 339 return le64_to_cpup((u64 *)addr); 340 } 341 342 u64 ioread64be(const void __iomem *addr) 343 { 344 if (unlikely(INDIRECT_ADDR(addr))) 345 return iomap_ops[ADDR_TO_REGION(addr)]->read64be(addr); 346 return *((u64 *)addr); 347 } 348 349 u64 ioread64_lo_hi(const void __iomem *addr) 350 { 351 u32 low, high; 352 353 low = ioread32(addr); 354 high = ioread32(addr + sizeof(u32)); 355 356 return low + ((u64)high << 32); 357 } 358 359 u64 ioread64_hi_lo(const void __iomem *addr) 360 { 361 u32 low, high; 362 363 high = ioread32(addr + sizeof(u32)); 364 low = ioread32(addr); 365 366 return low + ((u64)high << 32); 367 } 368 369 void iowrite8(u8 datum, void __iomem *addr) 370 { 371 if (unlikely(INDIRECT_ADDR(addr))) { 372 iomap_ops[ADDR_TO_REGION(addr)]->write8(datum, addr); 373 } else { 374 *((u8 *)addr) = datum; 375 } 376 } 377 378 void iowrite16(u16 datum, void __iomem *addr) 379 { 380 if (unlikely(INDIRECT_ADDR(addr))) { 381 iomap_ops[ADDR_TO_REGION(addr)]->write16(datum, addr); 382 } else { 383 *((u16 *)addr) = cpu_to_le16(datum); 384 } 385 } 386 387 void iowrite16be(u16 datum, void __iomem *addr) 388 { 389 if (unlikely(INDIRECT_ADDR(addr))) { 390 iomap_ops[ADDR_TO_REGION(addr)]->write16be(datum, addr); 391 } else { 392 *((u16 *)addr) = datum; 393 } 394 } 395 396 void iowrite32(u32 datum, void __iomem *addr) 397 { 398 if (unlikely(INDIRECT_ADDR(addr))) { 399 iomap_ops[ADDR_TO_REGION(addr)]->write32(datum, addr); 400 } else { 401 *((u32 *)addr) = cpu_to_le32(datum); 402 } 403 } 404 405 void iowrite32be(u32 datum, void __iomem *addr) 406 { 407 if (unlikely(INDIRECT_ADDR(addr))) { 408 iomap_ops[ADDR_TO_REGION(addr)]->write32be(datum, addr); 409 } else { 410 *((u32 *)addr) = datum; 411 } 412 } 413 414 void iowrite64(u64 datum, void __iomem *addr) 415 { 416 if (unlikely(INDIRECT_ADDR(addr))) { 417 iomap_ops[ADDR_TO_REGION(addr)]->write64(datum, addr); 418 } else { 419 *((u64 *)addr) = cpu_to_le64(datum); 420 } 421 } 422 423 void iowrite64be(u64 datum, void __iomem *addr) 424 { 425 if (unlikely(INDIRECT_ADDR(addr))) { 426 iomap_ops[ADDR_TO_REGION(addr)]->write64be(datum, addr); 427 } else { 428 *((u64 *)addr) = datum; 429 } 430 } 431 432 void iowrite64_lo_hi(u64 val, void __iomem *addr) 433 { 434 iowrite32(val, addr); 435 iowrite32(val >> 32, addr + sizeof(u32)); 436 } 437 438 void iowrite64_hi_lo(u64 val, void __iomem *addr) 439 { 440 iowrite32(val >> 32, addr + sizeof(u32)); 441 iowrite32(val, addr); 442 } 443 444 /* Repeating interfaces */ 445 446 void ioread8_rep(const void __iomem *addr, void *dst, unsigned long count) 447 { 448 if (unlikely(INDIRECT_ADDR(addr))) { 449 iomap_ops[ADDR_TO_REGION(addr)]->read8r(addr, dst, count); 450 } else { 451 while (count--) { 452 *(u8 *)dst = *(u8 *)addr; 453 dst++; 454 } 455 } 456 } 457 458 void ioread16_rep(const void __iomem *addr, void *dst, unsigned long count) 459 { 460 if (unlikely(INDIRECT_ADDR(addr))) { 461 iomap_ops[ADDR_TO_REGION(addr)]->read16r(addr, dst, count); 462 } else { 463 while (count--) { 464 *(u16 *)dst = *(u16 *)addr; 465 dst += 2; 466 } 467 } 468 } 469 470 void ioread32_rep(const void __iomem *addr, void *dst, unsigned long count) 471 { 472 if (unlikely(INDIRECT_ADDR(addr))) { 473 iomap_ops[ADDR_TO_REGION(addr)]->read32r(addr, dst, count); 474 } else { 475 while (count--) { 476 *(u32 *)dst = *(u32 *)addr; 477 dst += 4; 478 } 479 } 480 } 481 482 void iowrite8_rep(void __iomem *addr, const void *src, unsigned long count) 483 { 484 if (unlikely(INDIRECT_ADDR(addr))) { 485 iomap_ops[ADDR_TO_REGION(addr)]->write8r(addr, src, count); 486 } else { 487 while (count--) { 488 *(u8 *)addr = *(u8 *)src; 489 src++; 490 } 491 } 492 } 493 494 void iowrite16_rep(void __iomem *addr, const void *src, unsigned long count) 495 { 496 if (unlikely(INDIRECT_ADDR(addr))) { 497 iomap_ops[ADDR_TO_REGION(addr)]->write16r(addr, src, count); 498 } else { 499 while (count--) { 500 *(u16 *)addr = *(u16 *)src; 501 src += 2; 502 } 503 } 504 } 505 506 void iowrite32_rep(void __iomem *addr, const void *src, unsigned long count) 507 { 508 if (unlikely(INDIRECT_ADDR(addr))) { 509 iomap_ops[ADDR_TO_REGION(addr)]->write32r(addr, src, count); 510 } else { 511 while (count--) { 512 *(u32 *)addr = *(u32 *)src; 513 src += 4; 514 } 515 } 516 } 517 518 /* Mapping interfaces */ 519 520 void __iomem *ioport_map(unsigned long port, unsigned int nr) 521 { 522 return (void __iomem *)(IOPORT_MAP_BASE | port); 523 } 524 525 void ioport_unmap(void __iomem *addr) 526 { 527 if (!INDIRECT_ADDR(addr)) { 528 iounmap(addr); 529 } 530 } 531 532 #ifdef CONFIG_PCI 533 void pci_iounmap(struct pci_dev *dev, void __iomem * addr) 534 { 535 if (!INDIRECT_ADDR(addr)) { 536 iounmap(addr); 537 } 538 } 539 EXPORT_SYMBOL(pci_iounmap); 540 #endif 541 542 EXPORT_SYMBOL(ioread8); 543 EXPORT_SYMBOL(ioread16); 544 EXPORT_SYMBOL(ioread16be); 545 EXPORT_SYMBOL(ioread32); 546 EXPORT_SYMBOL(ioread32be); 547 EXPORT_SYMBOL(ioread64); 548 EXPORT_SYMBOL(ioread64be); 549 EXPORT_SYMBOL(ioread64_lo_hi); 550 EXPORT_SYMBOL(ioread64_hi_lo); 551 EXPORT_SYMBOL(iowrite8); 552 EXPORT_SYMBOL(iowrite16); 553 EXPORT_SYMBOL(iowrite16be); 554 EXPORT_SYMBOL(iowrite32); 555 EXPORT_SYMBOL(iowrite32be); 556 EXPORT_SYMBOL(iowrite64); 557 EXPORT_SYMBOL(iowrite64be); 558 EXPORT_SYMBOL(iowrite64_lo_hi); 559 EXPORT_SYMBOL(iowrite64_hi_lo); 560 EXPORT_SYMBOL(ioread8_rep); 561 EXPORT_SYMBOL(ioread16_rep); 562 EXPORT_SYMBOL(ioread32_rep); 563 EXPORT_SYMBOL(iowrite8_rep); 564 EXPORT_SYMBOL(iowrite16_rep); 565 EXPORT_SYMBOL(iowrite32_rep); 566 EXPORT_SYMBOL(ioport_map); 567 EXPORT_SYMBOL(ioport_unmap); 568